“Baby Mental Life: Study 1” was conducted on MTurk on 2018-07-31 through 2018-08-01.
Our planned sample was 300 participants, and we anticipated that roughly 85-90% of recruited participants would pass all of our attention checks, so we initially recruited 342 participants (on the idea that ~87.5% of 342 ~ 300 participants; note that for administrative purposes we need to recuit participants in batches that were divisible by 9). After filtering out participants who failed at least one of our attention checks, we ended up retaining only 80% of participants, so we recruited an additional 36 participants for a total of 378 people recruited (on the idea that ~80% of 378 ~ 300 participants; note that for administrative purposes we need to recuit participants in batches that were divisible by 9). In a slight deviation from our preregistered recruitment plan, we limited these additional 36 participants to women, because we had an unexpectedly large imbalance of men to women.
UPDATE: On 2018-08-09, KW discovered that there were many repeating GPS locations, a symptom of a recent outbreak of bots on MTurk. As of this date, these data have excluded any participants where there is another participant with an identical set of GPS coordinates as recorded by Qualtrics. This excluded an additional 76 participants (25%).
In the end, we ended up with a sample of 301 participants who passed our attention checks, 225 of whom came from unique GPS coordinates.
Each participant assessed children’s mental capacities at 3 target ages: newborns, 9-month-olds, and 5-year-olds. For each target, they rated 60 mental capacities on a scale from 0 (not at all capable) to 100 (completely capable).
For more details about the study, see our preregistration here.
# load required libraries
library(tidyverse)
[30m── [1mAttaching packages[22m ─────────────────────────────────────── tidyverse 1.2.1 ──[39m
[30m[32m✔[30m [34mggplot2[30m 3.0.0 [32m✔[30m [34mpurrr [30m 0.2.5
[32m✔[30m [34mtibble [30m 1.4.2 [32m✔[30m [34mdplyr [30m 0.7.6
[32m✔[30m [34mtidyr [30m 0.8.1 [32m✔[30m [34mstringr[30m 1.3.1
[32m✔[30m [34mreadr [30m 1.1.1 [32m✔[30m [34mforcats[30m 0.3.0[39m
[30m── [1mConflicts[22m ────────────────────────────────────────── tidyverse_conflicts() ──
[31m✖[30m [34mdplyr[30m::[32mfilter()[30m masks [34mstats[30m::filter()
[31m✖[30m [34mdplyr[30m::[32mlag()[30m masks [34mstats[30m::lag()[39m
library(langcog) # source: https://github.com/langcog/langcog-package
Attaching package: ‘langcog’
The following object is masked from ‘package:base’:
scale
library(psych)
Attaching package: ‘psych’
The following objects are masked from ‘package:ggplot2’:
%+%, alpha
library(lme4)
Loading required package: Matrix
Attaching package: ‘Matrix’
The following object is masked from ‘package:tidyr’:
expand
# set theme for ggplots
theme_set(theme_bw())
# run source code (extra home-made functions)
source("./scripts/max_factors_efa.R")
source("./scripts/plot_fun.R")
source("./scripts/reten_fun.R")
Data preparation
# load in de-identified raw data
d0 <- read.csv("./data/deidentified/baby_mental_life_s1_data.csv") %>% select(-X)
# make question key
question_key <- d0[1,] %>%
t() %>%
data.frame() %>%
rownames_to_column("question_qualtrics") %>%
rename("question_text" = X1) %>%
mutate(question = recode(question_qualtrics,
"Duration..in.seconds." = "Duration",
"Q2" = "Age",
"Q3" = "GenderSex",
"Q3_3_TEXT" = "GenderSex_fillIn",
"Q4" = "EnglishProf",
"Q5" = "FirstLang",
"Q5_2_TEXT" = "FirstLang_fillIn",
"Q18" = "RaceEthnicity",
"Q18_10_TEXT" = "RaceEthnicity_fillIn",
"Q19" = "Education",
"Q20" = "Income",
"Q21" = "MaritalStatus",
"Q21_6_TEXT" = "MaritalStatus_fillIn",
"Q22" = "HouseholdSize",
"Q23" = "Parent",
"Q25" = "ChildrenNumber",
"Q26" = "ChildrenYoungestAge",
"Q26_1_TEXT" = "ChildrenYoungestAge_fillIn1",
"Q26_2_TEXT" = "ChildrenYoungestAge_fillIn2",
"Q27" = "ChildrenOldestAge",
"Q27_1_TEXT" = "ChildrenOldestAge_fillIn1",
"Q27_2_TEXT" = "ChildrenOldestAge_fillIn2",
"Q28" = "Attention",
"Q29" = "Comments",
.default = question_qualtrics),
question = case_when(grepl("the following questions", question_text) ~
gsub("^.*extent is a ", "", question_text),
TRUE ~ question),
question = case_when(grepl("capable of...", question_text) ~
gsub("capable of... ", "", tolower(question)),
TRUE ~ question),
question = gsub(" ", "_", question),
question = gsub("'", "", question),
question = gsub("newborn_-_", "target00mo_", question),
question = gsub("9-month-old_-_", "target09mo_", question),
question = gsub("5-year-old_-_", "target60mo_", question)) %>%
mutate(question = gsub("-", "_", question),
question = gsub(" \\(for_example,_smooth,_rough\\)", "", question))
# rename questions
d1 <- d0 %>%
# get rid of extra info in first two rows
filter(!is.na(as.numeric(as.character(Q2)))) %>%
gather(question_qualtrics, response, -c(ResponseId, duplicateGPS)) %>%
left_join(question_key %>% select(question_qualtrics, question)) %>%
select(-question_qualtrics) %>%
spread(question, response)
NAs introduced by coercionattributes are not identical across measure variables;
they will be droppedJoining, by = "question_qualtrics"
# implement inclusion/exclusion criteria
d2 <- d1 %>%
filter(Age >= 18, Age <= 45,
EnglishProf %in% c("Advanced", "Superior"),
`target00mo_please_select_34` == 34,
`target09mo_please_select_90` == 90,
`target60mo_please_select_4` == 4,
Attention == "Yes")
# remove people with another identical set of GPS coordinates among people who passed attention checks
d3 <- d2 %>%
filter(duplicateGPS == F) %>%
select(-duplicateGPS)
# recode variables & drop extraneous variables
d4 <- d3 %>%
select(-c(EndDate, Finished,
payment, Progress,
RecordedDate, StartDate, Status,
timeEstimate, UserLanguage)) %>%
mutate_at(vars(c(starts_with("target"), Age, ChildrenNumber,
ChildrenOldestAge_fillIn1, ChildrenOldestAge_fillIn2,
ChildrenYoungestAge_fillIn1, ChildrenYoungestAge_fillIn2,
Duration, HouseholdSize)),
funs(as.numeric(.))) %>%
mutate(Education = factor(Education,
levels = c("No schooling completed",
"Nursery school to 8th grade",
"Some high school, no diploma",
"High school graduate, diploma or equivalent (including GED)",
"Some college credit, no degree",
"Trade school, technical school, or vocational school",
"Associate's degree (for example, AA, AS)",
"Bachelor's degree (for example, BA, BS)",
"Master's degree (for example, MA, MS)",
"Doctor or professional degree (for example, PhD, JD, MD, MBA)")),
Income = factor(Income,
levels = c("$5,001 - 15,000",
"$15,001 - 30,000",
"$30,001 - 60,000",
"$60,001 - 90,000",
"$90,001 - 150,000",
"Greater than $150,000",
"Prefer not to say")),
Parent = factor(Parent,
levels = c("No", "Yes")))
NAs introduced by coercion
# make useful datasets
# final dataset with all measured variables
d <- d4 %>% distinct()
# demographic information
d_demo <- d %>%
select(ResponseId, Duration,
Age, starts_with("GenderSex"), starts_with("RaceEthnicity"),
starts_with("FirstLang"),
Education, Income, HouseholdSize,
starts_with("MaritalStatus"),
Parent, starts_with("Children"),
Comments) %>%
mutate(RaceEthnicity_collapse = ifelse(grepl(",([A-Za-z])", RaceEthnicity),
"Multiple", RaceEthnicity)) %>%
mutate(ChildrenOldestAge_collapse = case_when(
ChildrenOldestAge %in% c("My oldest child has not yet been born (I am/my partner is pregnant)", "My oldest child is deceased", "Prefer not to say") ~ ChildrenOldestAge,
ChildrenOldestAge == "In months:" ~
ifelse(as.numeric(ChildrenOldestAge_fillIn1)/12 < 1,
"< 1 year",
ifelse(as.numeric(ChildrenOldestAge_fillIn1)/12 < 3,
"1 - 3 years",
ifelse(as.numeric(ChildrenOldestAge_fillIn1)/12 < 5,
"3 - 5 years",
ifelse(as.numeric(ChildrenOldestAge_fillIn1)/12 < 10,
"5 - 10 years",
ifelse(as.numeric(ChildrenOldestAge_fillIn1)/12 < 18,
"10 - 18 years",
"> 18 years"))))),
ChildrenOldestAge == "In years:" ~
ifelse(as.numeric(ChildrenOldestAge_fillIn2) < 1,
"< 1 year",
ifelse(as.numeric(ChildrenOldestAge_fillIn2) < 3,
"1 - 3 years",
ifelse(as.numeric(ChildrenOldestAge_fillIn2) < 5,
"3 - 5 years",
ifelse(as.numeric(ChildrenOldestAge_fillIn2) < 10,
"5 - 10 years",
ifelse(as.numeric(ChildrenOldestAge_fillIn2) < 18,
"10 - 18 years",
"> 18 years"))))),
TRUE ~ "NA")) %>%
mutate(ChildrenOldestAge_collapse =
factor(ChildrenOldestAge_collapse,
levels = c("My oldest child has not yet been born (I am/my partner is pregnant)",
"< 1 year",
"1 - 3 years",
"3 - 5 years",
"5 - 10 years",
"10 - 18 years",
"> 18 years",
"My oldest child is deceased",
"Prefer not to say"))) %>%
mutate(ChildrenYoungestAge_collapse = case_when(
ChildrenYoungestAge %in% c("My youngest child has not yet been born (I am/my partner is pregnant)", "My youngest child is deceased", "Prefer not to say") ~ ChildrenYoungestAge,
ChildrenYoungestAge == "In months:" ~
ifelse(as.numeric(ChildrenYoungestAge_fillIn1)/12 < 1,
"< 1 year",
ifelse(as.numeric(ChildrenYoungestAge_fillIn1)/12 < 3,
"1 - 3 years",
ifelse(as.numeric(ChildrenYoungestAge_fillIn1)/12 < 5,
"3 - 5 years",
ifelse(as.numeric(ChildrenYoungestAge_fillIn1)/12 < 10,
"5 - 10 years",
ifelse(as.numeric(ChildrenYoungestAge_fillIn1)/12 < 18,
"10 - 18 years",
"> 18 years"))))),
ChildrenYoungestAge == "In years:" ~
ifelse(as.numeric(ChildrenYoungestAge_fillIn2) < 1,
"< 1 year",
ifelse(as.numeric(ChildrenYoungestAge_fillIn2) < 3,
"1 - 3 years",
ifelse(as.numeric(ChildrenYoungestAge_fillIn2) < 5,
"3 - 5 years",
ifelse(as.numeric(ChildrenYoungestAge_fillIn2) < 10,
"5 - 10 years",
ifelse(as.numeric(ChildrenYoungestAge_fillIn2) < 18,
"10 - 18 years",
"> 18 years"))))),
TRUE ~ "NA")) %>%
mutate(ChildrenYoungestAge_collapse =
factor(ChildrenYoungestAge_collapse,
levels = c("My Youngest child has not yet been born (I am/my partner is pregnant)",
"< 1 year",
"1 - 3 years",
"3 - 5 years",
"5 - 10 years",
"10 - 18 years",
"> 18 years",
"My Youngest child is deceased",
"Prefer not to say")))
# all assessments of ALL TARGETS, RepsonseId as rownames
d_all <- d %>%
select(ResponseId, starts_with("target"), -contains("please_select")) %>%
gather(question, response, -ResponseId) %>%
mutate(target = gsub("_.*$", "", question),
capacity = gsub("target..mo_", "", question),
subid = paste(ResponseId, target, sep = "_")) %>%
select(-ResponseId, -question, -target) %>%
spread(capacity, response) %>%
column_to_rownames("subid")
# all assessments of NEWBORNS, RepsonseId as rownames
d_00mo <- d_all %>%
rownames_to_column("subid") %>%
filter(grepl("target00mo", subid)) %>%
mutate(subid = gsub("target..mo_", "", subid)) %>%
column_to_rownames("subid")
# all assessments of 9-MONTH-OLDS, RepsonseId as rownames
d_09mo <- d_all %>%
rownames_to_column("subid") %>%
filter(grepl("target09mo", subid)) %>%
mutate(subid = gsub("target..mo_", "", subid)) %>%
column_to_rownames("subid")
# all assessments of 5-YEAR-OLDS, RepsonseId as rownames
d_60mo <- d_all %>%
rownames_to_column("subid") %>%
filter(grepl("target60mo", subid)) %>%
mutate(subid = gsub("target..mo_", "", subid)) %>%
column_to_rownames("subid")
EFA: all targets
Our primary analysis is an exploratory factor analysis (EFA) collapsing across all 3 target characters (and treating an individual participant’s responses to each character as if they were independent data points) - see the preregistration for more details.
We planned to examine three factor retention protocols in order to determine how many factors to retain: Parallel analysis, minimizing BIC, and a set of preset criteria outlined in Weisman et al. (2017). Here we look at each solution in turn.
Rotation choices
We planned to examine oblimin-rotated solutions (which allow factors to correlate), but you could examine other rotation options by selecting a different rotation type here.
chosen_rot <- "oblimin" # preregistered: factors allowed to correlate
# chosen_rot <- "varimax" # orthogonal: factors forced not to correlate
# chosen_rot <- "none" # no rotation
Parallel analysis
How many factors to retain?
reten_all_PA <- fa.parallel(d_all, plot = F); reten_all_PA
Parallel analysis suggests that the number of factors = 4 and the number of components = 3
Call: fa.parallel(x = d_all, plot = F)
Parallel analysis suggests that the number of factors = 4 and the number of components = 3
Eigen Values of
reten_all_par <- reten_all_PA$nfact
What are these factors?
efa_all_par <- fa(d_all, nfactors = reten_all_par, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
Loading required namespace: GPArotation
A loading greater than abs(1) was detected. Examine the loadings carefully.
heatmap_fun(efa_all_par) +
labs(title = paste0("Parallel Analysis (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to which targets?
scoresplot_fun(efa_all_par, target = "all (study 1)") +
labs(title = "Parallel Analysis") +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))
Ignoring unknown aesthetics: y

Here’s a multilevel linear regression on these factor scores, with random intercepts and slopes (for target and factor) by participant. Target is coded with linear and quadratic contrasts, and factor is effect-coded for comparison with the grand mean (with the last factor as the base, -1):
efa_all_par_scores <- efa_all_par$scores[] %>%
data.frame() %>%
rownames_to_column("subid") %>%
mutate(target = gsub("^.*_target", "target", subid),
ResponseId = gsub("_target.*$", "", subid)) %>%
select(-subid) %>%
gather(factor, score, -target, -ResponseId) %>%
mutate_at(vars(target, factor), funs(factor))
contrasts(efa_all_par_scores$target) <- contr.poly(3)
contrasts(efa_all_par_scores$factor) <- contr.sum(reten_all_par)
r_all_par <- lmer(score ~ target * factor + (target + factor | ResponseId),
efa_all_par_scores)
summary(r_all_par, corr = F)
Linear mixed model fit by REML ['lmerMod']
Formula: score ~ target * factor + (target + factor | ResponseId)
Data: efa_all_par_scores
REML criterion at convergence: 5181
Scaled residuals:
Min 1Q Median 3Q Max
-4.2514 -0.5125 0.0304 0.5514 3.3609
Random effects:
Groups Name Variance Std.Dev. Corr
ResponseId (Intercept) 0.26818 0.5179
target.L 0.08540 0.2922 -0.44
target.Q 0.02459 0.1568 -0.90 0.35
factor1 0.11311 0.3363 -0.71 0.17 0.45
factor2 0.23800 0.4879 0.34 0.28 0.01 -0.71
factor3 0.02565 0.1602 -0.31 -0.22 0.43 0.53 -0.04
Residual 0.23513 0.4849
Number of obs: 2700, groups: ResponseId, 225
Fixed effects:
Estimate Std. Error t value
(Intercept) -2.187e-15 3.576e-02 0.000
target.L 8.496e-01 2.531e-02 33.560
target.Q 7.120e-02 1.925e-02 3.699
factor1 -4.474e-16 2.764e-02 0.000
factor2 2.641e-15 3.632e-02 0.000
factor3 7.033e-17 1.937e-02 0.000
target.L:factor1 5.125e-01 2.800e-02 18.308
target.Q:factor1 2.749e-01 2.800e-02 9.819
target.L:factor2 -4.397e-01 2.800e-02 -15.707
target.Q:factor2 -1.117e-01 2.800e-02 -3.990
target.L:factor3 3.288e-01 2.800e-02 11.745
target.Q:factor3 -2.922e-01 2.800e-02 -10.439
If we consider t-values > 2 to be “significant” and use the plot above to guide our interpretation, here’s what we conclude:
- [
(Intercept): By definition, because we’re using factor scores, which are similar to z-scores, the intercept is ~0.]
target.L: Overall, mental capacity attributions increase with target age.
target.Q: This increase is generally non-linear.
- [
factor1, factor2, …: By definition, because we’re using factor scores, which are similar to z-scores, the differences in means across factors are ~0.]
target.L:factor1: The linear increase is more dramatic (steeper slope) for MR1, compared to other factors.
target.Q:factor1: The nonlinearity is more dramatic (curvier and/or concave instead of convex curve) for MR1, compared to other factors.
target.L:factor2: The linear increase is less dramatic (shallower slope) for MR2, compared to other factors.
target.Q:factor2: The nonlinearity is less dramatic (flatter curve) for MR2, compared to other factors.
target.L:factor3: The linear increase is more dramatic (steeper slope) for MR3, compared to other factors.
target.Q:factor3: The nonlinearity is less dramatic (flatter curve) for MR3, compared to other factors.
itemsplot_fun(efa_all_par, target = "all") +
labs(title = "Parallel Analysis")
Joining, by = "capacity"
|========================================== | 78% ~1 s remaining
|=========================================== | 81% ~0 s remaining
|============================================ | 83% ~0 s remaining
|============================================== | 86% ~0 s remaining
|================================================ | 89% ~0 s remaining
|================================================= | 92% ~0 s remaining
|=================================================== | 95% ~0 s remaining
|===================================================== | 98% ~0 s remaining
Joining, by = c("capacity", "factor", "order")

Minimizing BIC
How many factors to retain?
reten_all_vss <- VSS(d_all, plot = F); reten_all_vss
Very Simple Structure
Call: vss(x = x, n = n, rotate = rotate, diagonal = diagonal, fm = fm,
n.obs = n.obs, plot = plot, title = title, use = use, cor = cor)
VSS complexity 1 achieves a maximimum of 0.96 with 1 factors
VSS complexity 2 achieves a maximimum of 0.99 with 2 factors
The Velicer MAP achieves a minimum of 0.01 with 6 factors
BIC achieves a minimum of -6032.72 with 6 factors
Sample Size adjusted BIC achieves a minimum of -1597.88 with 8 factors
Statistics by number of factors
reten_all_bic <- data.frame(reten_all_vss$vss.stats %>%
rownames_to_column("nfactors") %>%
top_n(-1, BIC) %>%
select(nfactors))$nfactors %>% as.numeric()
What are these factors?
efa_all_bic <- fa(d_all, nfactors = reten_all_bic, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
convergence not obtained in GPFoblq. 1000 iterations used. A loading greater than abs(1) was detected. Examine the loadings carefully.
heatmap_fun(efa_all_bic) +
labs(title = paste0("Minimizing BIC (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to which targets?
scoresplot_fun(efa_all_bic, target = "all (study 1)") +
labs(title = "Minimizing BIC") +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))
Ignoring unknown aesthetics: y

Here’s a multilevel linear regression on these factor scores, with random intercepts and slopes (for target and factor) by participant. Target is coded with linear and quadratic contrasts, and factor is effect-coded for comparison with the grand mean (with the last factor as the base, -1):
# efa_all_bic_scores <- efa_all_bic$scores[] %>%
# data.frame() %>%
# rownames_to_column("subid") %>%
# mutate(target = gsub("^.*_target", "target", subid),
# ResponseId = gsub("_target.*$", "", subid)) %>%
# select(-subid) %>%
# gather(factor, score, -target, -ResponseId) %>%
# mutate_at(vars(target, factor), funs(factor))
#
# contrasts(efa_all_bic_scores$target) <- contr.poly(3)
# contrasts(efa_all_bic_scores$factor) <- contr.sum(reten_all_bic)
#
# r_all_bic <- lmer(score ~ target * factor + (target + factor | ResponseId),
# efa_all_bic_scores,
# control = lmerControl(optCtrl = list(maxfun = 100000)))
# summary(r_all_bic, corr = F)
If we consider t-values > 2 to be “significant” and use the plot above to guide our interpretation, here’s what we conclude:
- [
(Intercept): By definition, because we’re using factor scores, which are similar to z-scores, the intercept is ~0.]
target.L: Overall, mental capacity attributions increase with target age.
target.Q: This increase is not generally non-linear.
- [
factor1, factor2, …: By definition, because we’re using factor scores, which are similar to z-scores, the differences in means across factors are ~0.]
target.L:factor1: The linear increase is more dramatic (steeper slope) for MR1, compared to other factors.
target.Q:factor1: The nonlinearity is more dramatic (curvier and/or concave instead of convex curve) for MR1, compared to other factors.
target.L:factor2: The linear increase is less dramatic (shallower slope) for MR2, compared to other factors.
target.Q:factor2: The nonlinearity for MR2 is comparable to other factors.
target.L:factor3: The linear increase is more dramatic (steeper slope) for MR3, compared to other factors.
target.Q:factor3: The nonlinearity is less dramatic (flatter curve) for MR3, compared to other factors.
target.L:factor4: The linear increase is less dramatic (shallower slope) for MR4, compared to other factors.
target.Q:factor4: The nonlinearity is more dramatic (curvier and/or concanve instead of convex curve) for MR4, compared to other factors.
target.L:factor5: The linear increase is more dramatic (steeper slope) for MR5, compared to other factors.
target.Q:factor5: The nonlinearity is less dramatic (flatter curve) for MR5, compared to other factors.
itemsplot_fun(efa_all_bic, target = "all") +
labs(title = "Minimizing BIC")
Joining, by = "capacity"
|============================================ | 82% ~0 s remaining
|============================================= | 85% ~0 s remaining
|=============================================== | 87% ~0 s remaining
|================================================ | 90% ~0 s remaining
|================================================= | 92% ~0 s remaining
|================================================== | 94% ~0 s remaining
|==================================================== | 97% ~0 s remaining
|===================================================== | 99% ~0 s remaining
Joining, by = c("capacity", "factor", "order")

Preset retention criteria
How many factors to retain?
reten_all_k <- reten_fun(d_all, rot_type = chosen_rot)
print(paste("Preset criteria suggest retaining", reten_all_k, "factors"))
[1] "Preset criteria suggest retaining 2 factors"
What are these factors?
efa_all_k <- fa(d_all, nfactors = reten_all_k, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
heatmap_fun(efa_all_k) +
labs(title = paste0("Preset criteria (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to which targets?
scoresplot_fun(efa_all_k, target = "all (study 1)") +
labs(title = "Preset factor retention criteria (Weisman et al., 2017)")
Ignoring unknown aesthetics: y

Here’s a multilevel linear regression on these factor scores, with random intercepts and slopes (for target and factor) by participant. Target is coded with linear and quadratic contrasts, and factor is effect-coded for comparison with the grand mean (with the last factor as the base, -1):
efa_all_k_scores <- efa_all_k$scores[] %>%
data.frame() %>%
rownames_to_column("subid") %>%
mutate(target = gsub("^.*_target", "target", subid),
ResponseId = gsub("_target.*$", "", subid)) %>%
select(-subid) %>%
gather(factor, score, -target, -ResponseId) %>%
mutate_at(vars(target, factor), funs(factor))
contrasts(efa_all_k_scores$target) <- contr.poly(3)
contrasts(efa_all_k_scores$factor) <- contr.sum(reten_all_k)
r_all_k <- lmer(score ~ target * factor + (target + factor | ResponseId),
efa_all_k_scores)
summary(r_all_k, corr = F)
Linear mixed model fit by REML ['lmerMod']
Formula: score ~ target * factor + (target + factor | ResponseId)
Data: efa_all_k_scores
REML criterion at convergence: 2466.4
Scaled residuals:
Min 1Q Median 3Q Max
-3.7025 -0.4841 0.0034 0.5413 2.7814
Random effects:
Groups Name Variance Std.Dev. Corr
ResponseId (Intercept) 0.26690 0.5166
target.L 0.08731 0.2955 -0.48
target.Q 0.02408 0.1552 -0.93 0.26
factor1 0.09109 0.3018 -0.63 -0.09 0.48
Residual 0.18763 0.4332
Number of obs: 1350, groups: ResponseId, 225
Fixed effects:
Estimate Std. Error t value
(Intercept) 3.800e-15 3.640e-02 0.000
target.L 1.050e+00 2.837e-02 36.991
target.Q 3.457e-02 2.289e-02 1.510
factor1 -1.095e-15 2.332e-02 0.000
target.L:factor1 3.327e-01 2.042e-02 16.292
target.Q:factor1 2.042e-01 2.042e-02 9.999
There are some problems with this model that I haven’t addressed - see warnings above. Ignoring them for now…
If we consider t-values > 2 to be “significant” and use the plot above to guide our interpretation, here’s what we conclude:
- [
(Intercept): By definition, because we’re using factor scores, which are similar to z-scores, the intercept is ~0.]
target.L: Overall, mental capacity attributions increase with target age.
target.Q: This increase is generally non-linear.
- [
factor1: By definition, because we’re using factor scores, which are similar to z-scores, the differences in means across factors are ~0.]
target.L:factor1: The linear increase is more dramatic (steeper slope) for MR1, compared to other factors.
target.Q:factor1: The nonlinearity is more dramatic (curvier and/or concave instead of convex curve) for MR1, compared to other factors.
itemsplot_fun(efa_all_k, target = "all") +
labs(title = "Preset factor retention criteria (Weisman et al., 2017)")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

EFA: newborns
What happens if we limit ourselves to assessments of newborns’ mental capacities?
Parallel analysis
How many factors to retain?
reten_00mo_PA <- fa.parallel(d_00mo, plot = F); reten_00mo_PA
Parallel analysis suggests that the number of factors = 4 and the number of components = 3
Call: fa.parallel(x = d_00mo, plot = F)
Parallel analysis suggests that the number of factors = 4 and the number of components = 3
Eigen Values of
reten_00mo_par <- reten_00mo_PA$nfact
What are these factors?
efa_00mo_par <- fa(d_00mo, nfactors = reten_00mo_par, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
heatmap_fun(efa_00mo_par) +
labs(title = paste0("Parallel Analysis (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to newborns?
itemsplot_fun(efa_00mo_par, target = "newborns") +
labs(title = "Parallel Analysis")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

Minimizing BIC
How many factors to retain?
reten_00mo_vss <- VSS(d_00mo, plot = F); reten_00mo_vss
Very Simple Structure
Call: vss(x = x, n = n, rotate = rotate, diagonal = diagonal, fm = fm,
n.obs = n.obs, plot = plot, title = title, use = use, cor = cor)
VSS complexity 1 achieves a maximimum of 0.83 with 1 factors
VSS complexity 2 achieves a maximimum of 0.94 with 2 factors
The Velicer MAP achieves a minimum of 0.01 with 5 factors
BIC achieves a minimum of -5953.64 with 3 factors
Sample Size adjusted BIC achieves a minimum of -1158.37 with 8 factors
Statistics by number of factors
reten_00mo_bic <- data.frame(reten_00mo_vss$vss.stats %>%
rownames_to_column("nfactors") %>%
top_n(-1, BIC) %>%
select(nfactors))$nfactors %>% as.numeric()
What are these factors?
efa_00mo_bic <- fa(d_00mo, nfactors = reten_00mo_bic, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
heatmap_fun(efa_00mo_bic) +
labs(title = paste0("Minimizing BIC (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to newborns?
itemsplot_fun(efa_00mo_bic, target = "newborns") +
labs(title = "Minimizing BIC")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

Preset retention criteria
How many factors to retain?
reten_00mo_k <- reten_fun(d_00mo, rot_type = chosen_rot)
print(paste("Preset criteria suggest retaining", reten_00mo_k, "factors"))
[1] "Preset criteria suggest retaining 2 factors"
What are these factors?
efa_00mo_k <- fa(d_00mo, nfactors = reten_00mo_k, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
heatmap_fun(efa_00mo_k) +
labs(title = paste0("Preset criteria (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to newborns?
itemsplot_fun(efa_00mo_k, target = "newborns") +
labs(title = "Preset factor retention criteria\n(Weisman et al., 2017)")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

EFA: 9-month-olds
What happens if we limit ourselves to assessments of 9-month-olds’ mental capacities?
Parallel analysis
How many factors to retain?
reten_09mo_PA <- fa.parallel(d_09mo, plot = F); reten_09mo_PA
Parallel analysis suggests that the number of factors = 4 and the number of components = 3
Call: fa.parallel(x = d_09mo, plot = F)
Parallel analysis suggests that the number of factors = 4 and the number of components = 3
Eigen Values of
reten_09mo_par <- reten_09mo_PA$nfact
What are these factors?
efa_09mo_par <- fa(d_09mo, nfactors = reten_09mo_par, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
heatmap_fun(efa_09mo_par) +
labs(title = paste0("Parallel analysis (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to 9-month-olds?
itemsplot_fun(efa_09mo_par, target = "9-month-olds") +
labs(title = "Parallel Analysis")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

Minimizing BIC
How many factors to retain?
reten_09mo_vss <- VSS(d_09mo, plot = F); reten_09mo_vss
Very Simple Structure
Call: vss(x = x, n = n, rotate = rotate, diagonal = diagonal, fm = fm,
n.obs = n.obs, plot = plot, title = title, use = use, cor = cor)
VSS complexity 1 achieves a maximimum of 0.9 with 1 factors
VSS complexity 2 achieves a maximimum of 0.98 with 2 factors
The Velicer MAP achieves a minimum of 0.01 with 5 factors
BIC achieves a minimum of -5884.26 with 4 factors
Sample Size adjusted BIC achieves a minimum of -1149.05 with 8 factors
Statistics by number of factors
reten_09mo_bic <- data.frame(reten_09mo_vss$vss.stats %>%
rownames_to_column("nfactors") %>%
top_n(-1, BIC) %>%
select(nfactors))$nfactors %>% as.numeric()
What are these factors?
efa_09mo_bic <- fa(d_09mo, nfactors = reten_09mo_bic, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
heatmap_fun(efa_09mo_bic) +
labs(title = paste0("Minimizing BIC (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to 9-month-olds?
itemsplot_fun(efa_09mo_bic, target = "9-month-olds") +
labs(title = "Minimizing BIC")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

Preset retention criteria
How many factors to retain?
reten_09mo_k <- reten_fun(d_09mo, rot_type = chosen_rot)
print(paste("Preset criteria suggest retaining", reten_09mo_k, "factors"))
[1] "Preset criteria suggest retaining 2 factors"
What are these factors?
efa_09mo_k <- fa(d_09mo, nfactors = reten_09mo_k, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
heatmap_fun(efa_09mo_k) +
labs(title = paste0("Preset criteria (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to 9-month-olds?
itemsplot_fun(efa_09mo_k, target = "9-month-olds") +
labs(title = "Preset factor retention criteria\n(Weisman et al., 2017)")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

EFA: 5-year-olds
What happens if we limit ourselves to assessments of 5-year-olds’ mental capacities?
Parallel analysis
How many factors to retain?
reten_60mo_PA <- fa.parallel(d_60mo, plot = F); reten_60mo_PA
Parallel analysis suggests that the number of factors = 3 and the number of components = 2
Call: fa.parallel(x = d_60mo, plot = F)
Parallel analysis suggests that the number of factors = 3 and the number of components = 2
Eigen Values of
reten_60mo_par <- reten_60mo_PA$nfact
What are these factors?
efa_60mo_par <- fa(d_60mo, nfactors = reten_60mo_par, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
A loading greater than abs(1) was detected. Examine the loadings carefully.
heatmap_fun(efa_60mo_par) +
labs(title = paste0("Parallel analysis (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to 5-year-olds?
itemsplot_fun(efa_60mo_par, target = "5-year-olds") +
labs(title = "Parallel Analysis")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

Minimizing BIC
How many factors to retain?
reten_60mo_vss <- VSS(d_60mo, plot = F); reten_60mo_vss
Very Simple Structure
Call: vss(x = x, n = n, rotate = rotate, diagonal = diagonal, fm = fm,
n.obs = n.obs, plot = plot, title = title, use = use, cor = cor)
VSS complexity 1 achieves a maximimum of 0.95 with 1 factors
VSS complexity 2 achieves a maximimum of 0.99 with 2 factors
The Velicer MAP achieves a minimum of 0.01 with 5 factors
BIC achieves a minimum of -4460.84 with 4 factors
Sample Size adjusted BIC achieves a minimum of 61.81 with 8 factors
Statistics by number of factors
reten_60mo_bic <- data.frame(reten_60mo_vss$vss.stats %>%
rownames_to_column("nfactors") %>%
top_n(-1, BIC) %>%
select(nfactors))$nfactors %>% as.numeric()
What are these factors?
efa_60mo_bic <- fa(d_60mo, nfactors = reten_60mo_bic, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
heatmap_fun(efa_60mo_bic) +
labs(title = paste0("Minimizing BIC (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to 5-year-olds?
itemsplot_fun(efa_60mo_bic, target = "5-year-olds") +
labs(title = "Minimizing BIC")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

Preset retention criteria
How many factors to retain?
reten_60mo_k <- reten_fun(d_60mo, rot_type = chosen_rot)
print(paste("Preset criteria suggest retaining", reten_60mo_k, "factors"))
[1] "Preset criteria suggest retaining 2 factors"
What are these factors?
efa_60mo_k <- fa(d_60mo, nfactors = reten_60mo_k, rotate = chosen_rot,
scores = "tenBerge", impute = "median")
heatmap_fun(efa_60mo_k) +
labs(title = paste0("Preset criteria (rotation: ", chosen_rot, ")"),
subtitle = "'% var.' indicates the amount of shared variance explained (total = 100%)")
Joining, by = "capacity"
Joining, by = "factor"

Which capacities are attributed to 5-year-olds?
itemsplot_fun(efa_60mo_k, target = "5-year-olds") +
labs(title = "Preset factor retention criteria\n(Weisman et al., 2017)")
Joining, by = "capacity"
Joining, by = c("capacity", "factor", "order")

Demographics
ggplot(d_demo, aes(x = Duration/60)) +
geom_histogram(binwidth = 2) +
geom_vline(xintercept = median(d_demo$Duration/60), color = "blue", lty = 2) +
scale_x_continuous(breaks = seq(0, 10000, 4)) +
labs(title = "Duration of study (according to Qualtrics)",
subtitle = "Blue dotted line marks median",
x = "Duration (in minutes)",
y = "Number of participants")

ggplot(d_demo, aes(x = Age)) +
geom_histogram(binwidth = 2) +
geom_vline(xintercept = median(d_demo$Age), color = "blue", lty = 2) +
scale_x_continuous(breaks = seq(0, 10000, 4)) +
labs(title = "Particpiant age (self-reported)",
subtitle = "Blue dotted line marks median",
x = "Age (in years)",
y = "Number of participants")

efa_all_par_scores %>%
mutate(ResponseId = as.character(ResponseId)) %>%
left_join(d_demo %>%
distinct(ResponseId, Age) %>%
mutate(ResponseId = as.character(ResponseId))) %>%
mutate(factor = factor(factor,
levels = c("MR1", "MR3", "MR2", "MR4"),
labels = c("cognition & control",
"positive & social emotions",
"bodily sensations",
"negative emotions"))) %>%
ggplot(aes(x = Age, y = score)) +
geom_hline(yintercept = 0, lty = 2) +
facet_grid(factor ~ target, scales = "free") +
# geom_point(alpha = 0.05) +
geom_smooth(method = "lm") +
scale_y_continuous(breaks = seq(-10, 10, 1))
Joining, by = "ResponseId"

ggplot(d_demo, aes(x = GenderSex)) +
geom_bar() +
labs(title = "Particpiant gender/sex (self-reported)",
x = "Gender/sex",
y = "Number of participants")

efa_all_par_scores %>%
mutate(ResponseId = as.character(ResponseId)) %>%
left_join(d_demo %>%
distinct(ResponseId, GenderSex) %>%
mutate(ResponseId = as.character(ResponseId))) %>%
filter(GenderSex %in% c("Female", "Male")) %>%
mutate(factor = factor(factor,
levels = c("MR1", "MR3", "MR2", "MR4"),
labels = c("cognition & control",
"positive & social emotions",
"bodily sensations",
"negative emotions"))) %>%
ggplot(aes(x = GenderSex, y = score)) +
facet_grid(factor ~ target, scales = "free") +
geom_hline(yintercept = 0, lty = 2) +
# geom_jitter(alpha = 0.05, height = 0) +
geom_pointrange(data = . %>%
group_by(target, factor, GenderSex) %>%
multi_boot_standard(col = "score") %>%
ungroup(),
aes(y = mean, ymin = ci_lower, ymax = ci_upper),
fatten = 1, color = "blue") +
scale_y_continuous(breaks = seq(-10, 10, 1)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))
Joining, by = "ResponseId"

ggplot(d_demo, aes(x = gsub('(.{1,30})(\\s|$)', '\\1\n', RaceEthnicity_collapse))) +
geom_bar() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
labs(title = "Particpiant race/ethnicity (self-reported)",
x = "Race/ethnicity",
y = "Number of participants")

ggplot(d_demo, aes(x = FirstLang)) +
geom_bar() +
labs(title = "Particpiant first language (self-reported)",
x = "Language",
y = "Number of participants")

ggplot(d_demo, aes(x = factor(Education,
levels = levels(d$Education),
labels = gsub('(.{1,30})(\\s|$)', '\\1\n',
levels(d$Education))))) +
geom_bar() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
labs(title = "Particpiant educational attainment (self-reported)",
x = "Highest level of education completed",
y = "Number of participants")

efa_all_par_scores %>%
mutate(ResponseId = as.character(ResponseId)) %>%
left_join(d_demo %>%
distinct(ResponseId, Education) %>%
mutate(ResponseId = as.character(ResponseId))) %>%
mutate(factor = factor(factor,
levels = c("MR1", "MR3", "MR2", "MR4"),
labels = c("cognition & control",
"positive & social emotions",
"bodily sensations",
"negative emotions")),
hi_low_ed = case_when(
as.numeric(Education) < 8 ~ "less than BA",
as.numeric(Education) >= 8 ~ "BA or more"),
hi_low_ed = factor(hi_low_ed,
levels =c("less than BA", "BA or more"))) %>%
ggplot(aes(x = hi_low_ed, y = score)) +
facet_grid(factor ~ target, scales = "free") +
geom_hline(yintercept = 0, lty = 2) +
# geom_jitter(alpha = 0.05, height = 0) +
geom_pointrange(data = . %>%
group_by(target, factor, hi_low_ed) %>%
multi_boot_standard(col = "score") %>%
ungroup(),
aes(y = mean, ymin = ci_lower, ymax = ci_upper),
fatten = 1, color = "blue") +
scale_y_continuous(breaks = seq(-10, 10, 1)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))
Joining, by = "ResponseId"

ggplot(d_demo, aes(x = Income)) +
geom_bar() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
labs(title = "Particpiant household income (self-reported)",
x = "Annual household income",
y = "Number of participants")

efa_all_par_scores %>%
mutate(ResponseId = as.character(ResponseId)) %>%
left_join(d_demo %>%
distinct(ResponseId, Income) %>%
mutate(ResponseId = as.character(ResponseId))) %>%
mutate(factor = factor(factor,
levels = c("MR1", "MR3", "MR2", "MR4"),
labels = c("cognition & control",
"positive & social emotions",
"bodily sensations",
"negative emotions")),
hi_low_inc = case_when(
as.numeric(Income) < 4 ~ "less than $60,001",
as.numeric(Income) >= 4 ~ "$60,001 or more"),
hi_low_inc = factor(hi_low_inc,
levels =c("less than $60,001", "$60,001 or more"))) %>%
filter(!is.na(hi_low_inc)) %>%
ggplot(aes(x = hi_low_inc, y = score)) +
facet_grid(factor ~ target, scales = "free") +
geom_hline(yintercept = 0, lty = 2) +
# geom_jitter(alpha = 0.05, height = 0) +
geom_pointrange(data = . %>%
group_by(target, factor, hi_low_inc) %>%
multi_boot_standard(col = "score") %>%
ungroup(),
aes(y = mean, ymin = ci_lower, ymax = ci_upper),
fatten = 1, color = "blue") +
scale_y_continuous(breaks = seq(-10, 10, 1)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))
Joining, by = "ResponseId"

ggplot(d_demo, aes(x = HouseholdSize)) +
geom_histogram(binwidth = 1) +
geom_vline(xintercept = median(d_demo$HouseholdSize), color = "blue", lty = 2) +
scale_x_continuous(breaks = seq(0, 10000, 1)) +
labs(title = "Particpiant household size (self-reported)",
subtitle = "Blue dotted line marks median",
x = "Number of people in household (adults and children)",
y = "Number of participants")

ggplot(d_demo, aes(x = MaritalStatus)) +
geom_bar() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
labs(title = "Particpiant marital status (self-reported)",
x = "Marital status",
y = "Number of participants")

ggplot(d_demo, aes(x = Parent)) +
geom_bar() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
labs(title = "Particpiant parent status (self-reported)",
subtitle = "'NA' indicates response of 'Prefer not to say'",
x = "Parent status",
y = "Number of participants")

efa_all_par_scores %>%
mutate(ResponseId = as.character(ResponseId)) %>%
left_join(d_demo %>%
distinct(ResponseId, Parent) %>%
mutate(ResponseId = as.character(ResponseId))) %>%
filter(!is.na(Parent)) %>%
mutate(factor = factor(factor,
levels = c("MR1", "MR3", "MR2", "MR4"),
labels = c("cognition & control",
"positive & social emotions",
"bodily sensations",
"negative emotions"))) %>%
ggplot(aes(x = Parent, y = score)) +
facet_grid(factor ~ target, scales = "free") +
geom_hline(yintercept = 0, lty = 2) +
# geom_jitter(alpha = 0.05, height = 0) +
geom_pointrange(data = . %>%
group_by(target, factor, Parent) %>%
multi_boot_standard(col = "score") %>%
ungroup(),
aes(y = mean, ymin = ci_lower, ymax = ci_upper),
fatten = 1, color = "blue") +
scale_y_continuous(breaks = seq(-10, 10, 1)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))
Joining, by = "ResponseId"

ggplot(d_demo %>% filter(Parent == "Yes"), aes(x = ChildrenNumber)) +
geom_histogram(binwidth = 1) +
geom_vline(xintercept = median(d_demo[d_demo$Parent == "Yes",]$ChildrenNumber, na.rm = T),
color = "blue", lty = 2) +
scale_x_continuous(breaks = seq(-1, 10000, 1)) +
labs(title = "Number of children among parents (self-reported)",
subtitle = "Blue dotted line marks median",
x = "Number of children (among parents)",
y = "Number of participants")

ggplot(d_demo %>% filter(Parent == "Yes"),
aes(x = factor(ChildrenOldestAge_collapse,
levels = levels(d_demo$ChildrenOldestAge_collapse),
labels = gsub('(.{1,30})(\\s|$)', '\\1\n',
levels(d_demo$ChildrenOldestAge_collapse))))) +
geom_bar() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
labs(title = "Age of oldest child among parents (self-reported)",
x = "Age of child in years (among parents)",
y = "Number of participants")

ggplot(d_demo %>% filter(Parent == "Yes"),
aes(x = factor(ChildrenYoungestAge_collapse,
levels = levels(d_demo$ChildrenYoungestAge_collapse),
labels = gsub('(.{1,30})(\\s|$)', '\\1\n',
levels(d_demo$ChildrenYoungestAge_collapse))))) +
geom_bar() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
labs(title = "Age of youngest child among parents (self-reported)",
x = "Age of child in years (among parents)",
y = "Number of participants")

Save EFA output
Finally, I’ll export the 4-factor EFA results to a saved file that I can draw on in our Study 2 analyses.
saveRDS(efa_all_par, file = "./s1_efa.rds")
write.csv(d_demo, file = "./s1_demo.csv")
write.csv(d_all, file = "./s1_data.csv")
LS0tCnRpdGxlOiAiQmFieSBNZW50YWwgTGlmZTogU3R1ZHkgMSIKZGF0ZTogMjAxOC0wOC0wMQpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQotLS0KCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBpbmNsdWRlID0gRn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy53aWR0aCA9IDMsIGZpZy5hc3AgPSAwLjY3KQpgYGAKCgoiQmFieSBNZW50YWwgTGlmZTogU3R1ZHkgMSIgd2FzIGNvbmR1Y3RlZCBvbiBNVHVyayBvbiAyMDE4LTA3LTMxIHRocm91Z2ggMjAxOC0wOC0wMS4KCk91ciBwbGFubmVkIHNhbXBsZSB3YXMgMzAwIHBhcnRpY2lwYW50cywgYW5kIHdlIGFudGljaXBhdGVkIHRoYXQgcm91Z2hseSA4NS05MCUgb2YgcmVjcnVpdGVkIHBhcnRpY2lwYW50cyB3b3VsZCBwYXNzIGFsbCBvZiBvdXIgYXR0ZW50aW9uIGNoZWNrcywgc28gd2UgaW5pdGlhbGx5IHJlY3J1aXRlZCAzNDIgcGFydGljaXBhbnRzIChvbiB0aGUgaWRlYSB0aGF0IH44Ny41JSBvZiAzNDIgfiAzMDAgcGFydGljaXBhbnRzOyBub3RlIHRoYXQgZm9yIGFkbWluaXN0cmF0aXZlIHB1cnBvc2VzIHdlIG5lZWQgdG8gcmVjdWl0IHBhcnRpY2lwYW50cyBpbiBiYXRjaGVzIHRoYXQgd2VyZSBkaXZpc2libGUgYnkgOSkuIEFmdGVyIGZpbHRlcmluZyBvdXQgcGFydGljaXBhbnRzIHdobyBmYWlsZWQgYXQgbGVhc3Qgb25lIG9mIG91ciBhdHRlbnRpb24gY2hlY2tzLCB3ZSBlbmRlZCB1cCByZXRhaW5pbmcgb25seSA4MCUgb2YgcGFydGljaXBhbnRzLCBzbyB3ZSByZWNydWl0ZWQgYW4gYWRkaXRpb25hbCAzNiBwYXJ0aWNpcGFudHMgZm9yIGEgdG90YWwgb2YgMzc4IHBlb3BsZSByZWNydWl0ZWQgKG9uIHRoZSBpZGVhIHRoYXQgfjgwJSBvZiAzNzggfiAzMDAgcGFydGljaXBhbnRzOyBub3RlIHRoYXQgZm9yIGFkbWluaXN0cmF0aXZlIHB1cnBvc2VzIHdlIG5lZWQgdG8gcmVjdWl0IHBhcnRpY2lwYW50cyBpbiBiYXRjaGVzIHRoYXQgd2VyZSBkaXZpc2libGUgYnkgOSkuIEluIGEgc2xpZ2h0IGRldmlhdGlvbiBmcm9tIG91ciBwcmVyZWdpc3RlcmVkIHJlY3J1aXRtZW50IHBsYW4sIHdlIGxpbWl0ZWQgdGhlc2UgYWRkaXRpb25hbCAzNiBwYXJ0aWNpcGFudHMgdG8gd29tZW4sIGJlY2F1c2Ugd2UgaGFkIGFuIHVuZXhwZWN0ZWRseSBsYXJnZSBpbWJhbGFuY2Ugb2YgbWVuIHRvIHdvbWVuLiAKCioqVVBEQVRFOiBPbiAyMDE4LTA4LTA5LCBLVyBkaXNjb3ZlcmVkIHRoYXQgdGhlcmUgd2VyZSBtYW55IHJlcGVhdGluZyBHUFMgbG9jYXRpb25zLCBhIHN5bXB0b20gb2YgYSByZWNlbnQgb3V0YnJlYWsgb2YgYm90cyBvbiBNVHVyay4gQXMgb2YgdGhpcyBkYXRlLCB0aGVzZSBkYXRhIGhhdmUgZXhjbHVkZWQgYW55IHBhcnRpY2lwYW50cyB3aGVyZSB0aGVyZSBpcyBhbm90aGVyIHBhcnRpY2lwYW50IHdpdGggYW4gaWRlbnRpY2FsIHNldCBvZiBHUFMgY29vcmRpbmF0ZXMgYXMgcmVjb3JkZWQgYnkgUXVhbHRyaWNzLiBUaGlzIGV4Y2x1ZGVkIGFuIGFkZGl0aW9uYWwgNzYgcGFydGljaXBhbnRzICgyNSUpLioqCgpJbiB0aGUgZW5kLCB3ZSBlbmRlZCB1cCB3aXRoIGEgc2FtcGxlIG9mIDMwMSBwYXJ0aWNpcGFudHMgd2hvIHBhc3NlZCBvdXIgYXR0ZW50aW9uIGNoZWNrcywgMjI1IG9mIHdob20gY2FtZSBmcm9tIHVuaXF1ZSBHUFMgY29vcmRpbmF0ZXMuCgpFYWNoIHBhcnRpY2lwYW50IGFzc2Vzc2VkIGNoaWxkcmVuJ3MgbWVudGFsIGNhcGFjaXRpZXMgYXQgMyB0YXJnZXQgYWdlczogbmV3Ym9ybnMsIDktbW9udGgtb2xkcywgYW5kIDUteWVhci1vbGRzLiBGb3IgZWFjaCB0YXJnZXQsIHRoZXkgcmF0ZWQgNjAgbWVudGFsIGNhcGFjaXRpZXMgb24gYSBzY2FsZSBmcm9tIDAgKG5vdCBhdCBhbGwgY2FwYWJsZSkgdG8gMTAwIChjb21wbGV0ZWx5IGNhcGFibGUpLiAKCkZvciBtb3JlIGRldGFpbHMgYWJvdXQgdGhlIHN0dWR5LCBzZWUgb3VyIHByZXJlZ2lzdHJhdGlvbiBbaGVyZV0oaHR0cHM6Ly9vc2YuaW8vZTZhamgvKS4gCgpgYGB7cn0KIyBsb2FkIHJlcXVpcmVkIGxpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsYW5nY29nKSAjIHNvdXJjZTogaHR0cHM6Ly9naXRodWIuY29tL2xhbmdjb2cvbGFuZ2NvZy1wYWNrYWdlCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkobG1lNCkKCiMgc2V0IHRoZW1lIGZvciBnZ3Bsb3RzCnRoZW1lX3NldCh0aGVtZV9idygpKQpgYGAKCmBgYHtyfQojIHJ1biBzb3VyY2UgY29kZSAoZXh0cmEgaG9tZS1tYWRlIGZ1bmN0aW9ucykKc291cmNlKCIuL3NjcmlwdHMvbWF4X2ZhY3RvcnNfZWZhLlIiKQpzb3VyY2UoIi4vc2NyaXB0cy9wbG90X2Z1bi5SIikKc291cmNlKCIuL3NjcmlwdHMvcmV0ZW5fZnVuLlIiKQpgYGAKCgojIERhdGEgcHJlcGFyYXRpb24KCmBgYHtyfQojIGxvYWQgaW4gZGUtaWRlbnRpZmllZCByYXcgZGF0YQpkMCA8LSByZWFkLmNzdigiLi9kYXRhL2RlaWRlbnRpZmllZC9iYWJ5X21lbnRhbF9saWZlX3MxX2RhdGEuY3N2IikgJT4lIHNlbGVjdCgtWCkKYGBgCgpgYGB7cn0KIyBtYWtlIHF1ZXN0aW9uIGtleQpxdWVzdGlvbl9rZXkgPC0gZDBbMSxdICU+JQogIHQoKSAlPiUKICBkYXRhLmZyYW1lKCkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJxdWVzdGlvbl9xdWFsdHJpY3MiKSAlPiUKICByZW5hbWUoInF1ZXN0aW9uX3RleHQiID0gWDEpICU+JQogIG11dGF0ZShxdWVzdGlvbiA9IHJlY29kZShxdWVzdGlvbl9xdWFsdHJpY3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJEdXJhdGlvbi4uaW4uc2Vjb25kcy4iID0gIkR1cmF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlEyIiA9ICJBZ2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiUTMiID0gIkdlbmRlclNleCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJRM18zX1RFWFQiID0gIkdlbmRlclNleF9maWxsSW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiUTQiID0gIkVuZ2xpc2hQcm9mIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlE1IiA9ICJGaXJzdExhbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiUTVfMl9URVhUIiA9ICJGaXJzdExhbmdfZmlsbEluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlExOCIgPSAiUmFjZUV0aG5pY2l0eSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJRMThfMTBfVEVYVCIgPSAiUmFjZUV0aG5pY2l0eV9maWxsSW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiUTE5IiA9ICJFZHVjYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiUTIwIiA9ICJJbmNvbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiUTIxIiA9ICJNYXJpdGFsU3RhdHVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlEyMV82X1RFWFQiID0gIk1hcml0YWxTdGF0dXNfZmlsbEluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlEyMiIgPSAiSG91c2Vob2xkU2l6ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJRMjMiID0gIlBhcmVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJRMjUiID0gIkNoaWxkcmVuTnVtYmVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlEyNiIgPSAiQ2hpbGRyZW5Zb3VuZ2VzdEFnZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJRMjZfMV9URVhUIiA9ICJDaGlsZHJlbllvdW5nZXN0QWdlX2ZpbGxJbjEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiUTI2XzJfVEVYVCIgPSAiQ2hpbGRyZW5Zb3VuZ2VzdEFnZV9maWxsSW4yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlEyNyIgPSAiQ2hpbGRyZW5PbGRlc3RBZ2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiUTI3XzFfVEVYVCIgPSAiQ2hpbGRyZW5PbGRlc3RBZ2VfZmlsbEluMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJRMjdfMl9URVhUIiA9ICJDaGlsZHJlbk9sZGVzdEFnZV9maWxsSW4yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlEyOCIgPSAiQXR0ZW50aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlEyOSIgPSAiQ29tbWVudHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAuZGVmYXVsdCA9IHF1ZXN0aW9uX3F1YWx0cmljcyksCiAgICAgICAgIHF1ZXN0aW9uID0gY2FzZV93aGVuKGdyZXBsKCJ0aGUgZm9sbG93aW5nIHF1ZXN0aW9ucyIsIHF1ZXN0aW9uX3RleHQpIH4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc3ViKCJeLipleHRlbnQgaXMgYSAiLCAiIiwgcXVlc3Rpb25fdGV4dCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBxdWVzdGlvbiksCiAgICAgICAgIHF1ZXN0aW9uID0gY2FzZV93aGVuKGdyZXBsKCJjYXBhYmxlIG9mLi4uIiwgcXVlc3Rpb25fdGV4dCkgfgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdzdWIoImNhcGFibGUgb2YuLi4gIiwgIiIsIHRvbG93ZXIocXVlc3Rpb24pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IHF1ZXN0aW9uKSwKICAgICAgICAgcXVlc3Rpb24gPSBnc3ViKCIgIiwgIl8iLCBxdWVzdGlvbiksCiAgICAgICAgIHF1ZXN0aW9uID0gZ3N1YigiJyIsICIiLCBxdWVzdGlvbiksCiAgICAgICAgIHF1ZXN0aW9uID0gZ3N1YigibmV3Ym9ybl8tXyIsICJ0YXJnZXQwMG1vXyIsIHF1ZXN0aW9uKSwKICAgICAgICAgcXVlc3Rpb24gPSBnc3ViKCI5LW1vbnRoLW9sZF8tXyIsICJ0YXJnZXQwOW1vXyIsIHF1ZXN0aW9uKSwKICAgICAgICAgcXVlc3Rpb24gPSBnc3ViKCI1LXllYXItb2xkXy1fIiwgInRhcmdldDYwbW9fIiwgcXVlc3Rpb24pKSAlPiUKICBtdXRhdGUocXVlc3Rpb24gPSBnc3ViKCItIiwgIl8iLCBxdWVzdGlvbiksCiAgICAgICAgIHF1ZXN0aW9uID0gZ3N1YigiIFxcKGZvcl9leGFtcGxlLF9zbW9vdGgsX3JvdWdoXFwpIiwgIiIsIHF1ZXN0aW9uKSkKYGBgCgpgYGB7cn0KIyByZW5hbWUgcXVlc3Rpb25zCmQxIDwtIGQwICU+JQogICMgZ2V0IHJpZCBvZiBleHRyYSBpbmZvIGluIGZpcnN0IHR3byByb3dzICAKICBmaWx0ZXIoIWlzLm5hKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKFEyKSkpKSAlPiUgCiAgZ2F0aGVyKHF1ZXN0aW9uX3F1YWx0cmljcywgcmVzcG9uc2UsIC1jKFJlc3BvbnNlSWQsIGR1cGxpY2F0ZUdQUykpICU+JQogIGxlZnRfam9pbihxdWVzdGlvbl9rZXkgJT4lIHNlbGVjdChxdWVzdGlvbl9xdWFsdHJpY3MsIHF1ZXN0aW9uKSkgJT4lCiAgc2VsZWN0KC1xdWVzdGlvbl9xdWFsdHJpY3MpICU+JQogIHNwcmVhZChxdWVzdGlvbiwgcmVzcG9uc2UpCmBgYAoKYGBge3J9CiMgaW1wbGVtZW50IGluY2x1c2lvbi9leGNsdXNpb24gY3JpdGVyaWEKZDIgPC0gZDEgJT4lCiAgZmlsdGVyKEFnZSA+PSAxOCwgQWdlIDw9IDQ1LAogICAgICAgICBFbmdsaXNoUHJvZiAlaW4lIGMoIkFkdmFuY2VkIiwgIlN1cGVyaW9yIiksCiAgICAgICAgIGB0YXJnZXQwMG1vX3BsZWFzZV9zZWxlY3RfMzRgID09IDM0LAogICAgICAgICBgdGFyZ2V0MDltb19wbGVhc2Vfc2VsZWN0XzkwYCA9PSA5MCwKICAgICAgICAgYHRhcmdldDYwbW9fcGxlYXNlX3NlbGVjdF80YCA9PSA0LAogICAgICAgICBBdHRlbnRpb24gPT0gIlllcyIpCmBgYAoKYGBge3J9CiMgcmVtb3ZlIHBlb3BsZSB3aXRoIGFub3RoZXIgaWRlbnRpY2FsIHNldCBvZiBHUFMgY29vcmRpbmF0ZXMgYW1vbmcgcGVvcGxlIHdobyBwYXNzZWQgYXR0ZW50aW9uIGNoZWNrcwpkMyA8LSBkMiAlPiUKICBmaWx0ZXIoZHVwbGljYXRlR1BTID09IEYpICU+JQogIHNlbGVjdCgtZHVwbGljYXRlR1BTKQpgYGAKCgpgYGB7cn0KIyByZWNvZGUgdmFyaWFibGVzICYgZHJvcCBleHRyYW5lb3VzIHZhcmlhYmxlcwpkNCA8LSBkMyAlPiUKICBzZWxlY3QoLWMoRW5kRGF0ZSwgRmluaXNoZWQsIAogICAgICAgICAgICBwYXltZW50LCBQcm9ncmVzcywgCiAgICAgICAgICAgIFJlY29yZGVkRGF0ZSwgU3RhcnREYXRlLCBTdGF0dXMsIAogICAgICAgICAgICB0aW1lRXN0aW1hdGUsIFVzZXJMYW5ndWFnZSkpICU+JQogIG11dGF0ZV9hdCh2YXJzKGMoc3RhcnRzX3dpdGgoInRhcmdldCIpLCBBZ2UsIENoaWxkcmVuTnVtYmVyLCAKICAgICAgICAgICAgICAgICAgIENoaWxkcmVuT2xkZXN0QWdlX2ZpbGxJbjEsIENoaWxkcmVuT2xkZXN0QWdlX2ZpbGxJbjIsIAogICAgICAgICAgICAgICAgICAgQ2hpbGRyZW5Zb3VuZ2VzdEFnZV9maWxsSW4xLCBDaGlsZHJlbllvdW5nZXN0QWdlX2ZpbGxJbjIsCiAgICAgICAgICAgICAgICAgICBEdXJhdGlvbiwgSG91c2Vob2xkU2l6ZSkpLAogICAgICAgICAgICBmdW5zKGFzLm51bWVyaWMoLikpKSAlPiUKICBtdXRhdGUoRWR1Y2F0aW9uID0gZmFjdG9yKEVkdWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk5vIHNjaG9vbGluZyBjb21wbGV0ZWQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk51cnNlcnkgc2Nob29sIHRvIDh0aCBncmFkZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU29tZSBoaWdoIHNjaG9vbCwgbm8gZGlwbG9tYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSGlnaCBzY2hvb2wgZ3JhZHVhdGUsIGRpcGxvbWEgb3IgZXF1aXZhbGVudCAoaW5jbHVkaW5nIEdFRCkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNvbWUgY29sbGVnZSBjcmVkaXQsIG5vIGRlZ3JlZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJhZGUgc2Nob29sLCB0ZWNobmljYWwgc2Nob29sLCBvciB2b2NhdGlvbmFsIHNjaG9vbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBc3NvY2lhdGUncyBkZWdyZWUgKGZvciBleGFtcGxlLCBBQSwgQVMpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhY2hlbG9yJ3MgZGVncmVlIChmb3IgZXhhbXBsZSwgQkEsIEJTKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYXN0ZXIncyBkZWdyZWUgKGZvciBleGFtcGxlLCBNQSwgTVMpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRvY3RvciBvciBwcm9mZXNzaW9uYWwgZGVncmVlIChmb3IgZXhhbXBsZSwgUGhELCBKRCwgTUQsIE1CQSkiKSksCiAgICAgICAgIEluY29tZSA9IGZhY3RvcihJbmNvbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCIkNSwwMDEgLSAxNSwwMDAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiQxNSwwMDEgLSAzMCwwMDAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiQzMCwwMDEgLSA2MCwwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJDYwLDAwMSAtIDkwLDAwMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkOTAsMDAxIC0gMTUwLDAwMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHcmVhdGVyIHRoYW4gJDE1MCwwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJlZmVyIG5vdCB0byBzYXkiKSksCiAgICAgICAgIFBhcmVudCA9IGZhY3RvcihQYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJObyIsICJZZXMiKSkpCmBgYAoKYGBge3J9CiMgbWFrZSB1c2VmdWwgZGF0YXNldHMKIyBmaW5hbCBkYXRhc2V0IHdpdGggYWxsIG1lYXN1cmVkIHZhcmlhYmxlcwpkIDwtIGQ0ICU+JSBkaXN0aW5jdCgpCgojIGRlbW9ncmFwaGljIGluZm9ybWF0aW9uCmRfZGVtbyA8LSBkICU+JSAKICBzZWxlY3QoUmVzcG9uc2VJZCwgRHVyYXRpb24sCiAgICAgICAgIEFnZSwgc3RhcnRzX3dpdGgoIkdlbmRlclNleCIpLCBzdGFydHNfd2l0aCgiUmFjZUV0aG5pY2l0eSIpLAogICAgICAgICBzdGFydHNfd2l0aCgiRmlyc3RMYW5nIiksCiAgICAgICAgIEVkdWNhdGlvbiwgSW5jb21lLCBIb3VzZWhvbGRTaXplLAogICAgICAgICBzdGFydHNfd2l0aCgiTWFyaXRhbFN0YXR1cyIpLAogICAgICAgICBQYXJlbnQsIHN0YXJ0c193aXRoKCJDaGlsZHJlbiIpLCAKICAgICAgICAgQ29tbWVudHMpICU+JQogIG11dGF0ZShSYWNlRXRobmljaXR5X2NvbGxhcHNlID0gaWZlbHNlKGdyZXBsKCIsKFtBLVphLXpdKSIsIFJhY2VFdGhuaWNpdHkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNdWx0aXBsZSIsIFJhY2VFdGhuaWNpdHkpKSAlPiUKICBtdXRhdGUoQ2hpbGRyZW5PbGRlc3RBZ2VfY29sbGFwc2UgPSBjYXNlX3doZW4oCiAgICBDaGlsZHJlbk9sZGVzdEFnZSAlaW4lIGMoIk15IG9sZGVzdCBjaGlsZCBoYXMgbm90IHlldCBiZWVuIGJvcm4gKEkgYW0vbXkgcGFydG5lciBpcyBwcmVnbmFudCkiLCAiTXkgb2xkZXN0IGNoaWxkIGlzIGRlY2Vhc2VkIiwgIlByZWZlciBub3QgdG8gc2F5IikgfiBDaGlsZHJlbk9sZGVzdEFnZSwKICAgIENoaWxkcmVuT2xkZXN0QWdlID09ICJJbiBtb250aHM6IiB+IAogICAgICBpZmVsc2UoYXMubnVtZXJpYyhDaGlsZHJlbk9sZGVzdEFnZV9maWxsSW4xKS8xMiA8IDEsCiAgICAgICAgICAgICAiPCAxIHllYXIiLAogICAgICAgICAgICAgaWZlbHNlKGFzLm51bWVyaWMoQ2hpbGRyZW5PbGRlc3RBZ2VfZmlsbEluMSkvMTIgPCAzLCAKICAgICAgICAgICAgICAgICAgICAiMSAtIDMgeWVhcnMiLAogICAgICAgICAgICAgICAgICAgIGlmZWxzZShhcy5udW1lcmljKENoaWxkcmVuT2xkZXN0QWdlX2ZpbGxJbjEpLzEyIDwgNSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIzIC0gNSB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShhcy5udW1lcmljKENoaWxkcmVuT2xkZXN0QWdlX2ZpbGxJbjEpLzEyIDwgMTAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjUgLSAxMCB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoYXMubnVtZXJpYyhDaGlsZHJlbk9sZGVzdEFnZV9maWxsSW4xKS8xMiA8IDE4LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAgLSAxOCB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIj4gMTggeWVhcnMiKSkpKSksCiAgICBDaGlsZHJlbk9sZGVzdEFnZSA9PSAiSW4geWVhcnM6IiB+CiAgICAgIGlmZWxzZShhcy5udW1lcmljKENoaWxkcmVuT2xkZXN0QWdlX2ZpbGxJbjIpIDwgMSwKICAgICAgICAgICAgICI8IDEgeWVhciIsCiAgICAgICAgICAgICBpZmVsc2UoYXMubnVtZXJpYyhDaGlsZHJlbk9sZGVzdEFnZV9maWxsSW4yKSA8IDMsIAogICAgICAgICAgICAgICAgICAgICIxIC0gMyB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGFzLm51bWVyaWMoQ2hpbGRyZW5PbGRlc3RBZ2VfZmlsbEluMikgPCA1LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIjMgLSA1IHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGFzLm51bWVyaWMoQ2hpbGRyZW5PbGRlc3RBZ2VfZmlsbEluMikgPCAxMCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNSAtIDEwIHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShhcy5udW1lcmljKENoaWxkcmVuT2xkZXN0QWdlX2ZpbGxJbjIpIDwgMTgsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCAtIDE4IHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPiAxOCB5ZWFycyIpKSkpKSwKICAgIFRSVUUgfiAiTkEiKSkgJT4lCiAgbXV0YXRlKENoaWxkcmVuT2xkZXN0QWdlX2NvbGxhcHNlID0gCiAgICAgICAgICAgZmFjdG9yKENoaWxkcmVuT2xkZXN0QWdlX2NvbGxhcHNlLAogICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNeSBvbGRlc3QgY2hpbGQgaGFzIG5vdCB5ZXQgYmVlbiBib3JuIChJIGFtL215IHBhcnRuZXIgaXMgcHJlZ25hbnQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPCAxIHllYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxIC0gMyB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjMgLSA1IHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNSAtIDEwIHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAgLSAxOCB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIj4gMTggeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNeSBvbGRlc3QgY2hpbGQgaXMgZGVjZWFzZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQcmVmZXIgbm90IHRvIHNheSIpKSkgJT4lCiAgbXV0YXRlKENoaWxkcmVuWW91bmdlc3RBZ2VfY29sbGFwc2UgPSBjYXNlX3doZW4oCiAgICBDaGlsZHJlbllvdW5nZXN0QWdlICVpbiUgYygiTXkgeW91bmdlc3QgY2hpbGQgaGFzIG5vdCB5ZXQgYmVlbiBib3JuIChJIGFtL215IHBhcnRuZXIgaXMgcHJlZ25hbnQpIiwgIk15IHlvdW5nZXN0IGNoaWxkIGlzIGRlY2Vhc2VkIiwgIlByZWZlciBub3QgdG8gc2F5IikgfiBDaGlsZHJlbllvdW5nZXN0QWdlLAogICAgQ2hpbGRyZW5Zb3VuZ2VzdEFnZSA9PSAiSW4gbW9udGhzOiIgfiAKICAgICAgaWZlbHNlKGFzLm51bWVyaWMoQ2hpbGRyZW5Zb3VuZ2VzdEFnZV9maWxsSW4xKS8xMiA8IDEsCiAgICAgICAgICAgICAiPCAxIHllYXIiLAogICAgICAgICAgICAgaWZlbHNlKGFzLm51bWVyaWMoQ2hpbGRyZW5Zb3VuZ2VzdEFnZV9maWxsSW4xKS8xMiA8IDMsIAogICAgICAgICAgICAgICAgICAgICIxIC0gMyB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGFzLm51bWVyaWMoQ2hpbGRyZW5Zb3VuZ2VzdEFnZV9maWxsSW4xKS8xMiA8IDUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMyAtIDUgeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoYXMubnVtZXJpYyhDaGlsZHJlbllvdW5nZXN0QWdlX2ZpbGxJbjEpLzEyIDwgMTAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjUgLSAxMCB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoYXMubnVtZXJpYyhDaGlsZHJlbllvdW5nZXN0QWdlX2ZpbGxJbjEpLzEyIDwgMTgsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCAtIDE4IHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPiAxOCB5ZWFycyIpKSkpKSwKICAgIENoaWxkcmVuWW91bmdlc3RBZ2UgPT0gIkluIHllYXJzOiIgfgogICAgICBpZmVsc2UoYXMubnVtZXJpYyhDaGlsZHJlbllvdW5nZXN0QWdlX2ZpbGxJbjIpIDwgMSwKICAgICAgICAgICAgICI8IDEgeWVhciIsCiAgICAgICAgICAgICBpZmVsc2UoYXMubnVtZXJpYyhDaGlsZHJlbllvdW5nZXN0QWdlX2ZpbGxJbjIpIDwgMywgCiAgICAgICAgICAgICAgICAgICAgIjEgLSAzIHllYXJzIiwKICAgICAgICAgICAgICAgICAgICBpZmVsc2UoYXMubnVtZXJpYyhDaGlsZHJlbllvdW5nZXN0QWdlX2ZpbGxJbjIpIDwgNSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIzIC0gNSB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShhcy5udW1lcmljKENoaWxkcmVuWW91bmdlc3RBZ2VfZmlsbEluMikgPCAxMCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNSAtIDEwIHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShhcy5udW1lcmljKENoaWxkcmVuWW91bmdlc3RBZ2VfZmlsbEluMikgPCAxOCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwIC0gMTggeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI+IDE4IHllYXJzIikpKSkpLAogICAgVFJVRSB+ICJOQSIpKSAlPiUKICBtdXRhdGUoQ2hpbGRyZW5Zb3VuZ2VzdEFnZV9jb2xsYXBzZSA9IAogICAgICAgICAgIGZhY3RvcihDaGlsZHJlbllvdW5nZXN0QWdlX2NvbGxhcHNlLAogICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNeSBZb3VuZ2VzdCBjaGlsZCBoYXMgbm90IHlldCBiZWVuIGJvcm4gKEkgYW0vbXkgcGFydG5lciBpcyBwcmVnbmFudCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8IDEgeWVhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEgLSAzIHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMyAtIDUgeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICI1IC0gMTAgeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCAtIDE4IHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPiAxOCB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk15IFlvdW5nZXN0IGNoaWxkIGlzIGRlY2Vhc2VkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJlZmVyIG5vdCB0byBzYXkiKSkpICAKIyBhbGwgYXNzZXNzbWVudHMgb2YgQUxMIFRBUkdFVFMsIFJlcHNvbnNlSWQgYXMgcm93bmFtZXMKZF9hbGwgPC0gZCAlPiUgCiAgc2VsZWN0KFJlc3BvbnNlSWQsIHN0YXJ0c193aXRoKCJ0YXJnZXQiKSwgLWNvbnRhaW5zKCJwbGVhc2Vfc2VsZWN0IikpICU+JQogIGdhdGhlcihxdWVzdGlvbiwgcmVzcG9uc2UsIC1SZXNwb25zZUlkKSAlPiUKICBtdXRhdGUodGFyZ2V0ID0gZ3N1YigiXy4qJCIsICIiLCBxdWVzdGlvbiksCiAgICAgICAgIGNhcGFjaXR5ID0gZ3N1YigidGFyZ2V0Li5tb18iLCAiIiwgcXVlc3Rpb24pLAogICAgICAgICBzdWJpZCA9IHBhc3RlKFJlc3BvbnNlSWQsIHRhcmdldCwgc2VwID0gIl8iKSkgJT4lCiAgc2VsZWN0KC1SZXNwb25zZUlkLCAtcXVlc3Rpb24sIC10YXJnZXQpICU+JQogIHNwcmVhZChjYXBhY2l0eSwgcmVzcG9uc2UpICU+JQogIGNvbHVtbl90b19yb3duYW1lcygic3ViaWQiKQoKIyBhbGwgYXNzZXNzbWVudHMgb2YgTkVXQk9STlMsIFJlcHNvbnNlSWQgYXMgcm93bmFtZXMKZF8wMG1vIDwtIGRfYWxsICU+JSAKICByb3duYW1lc190b19jb2x1bW4oInN1YmlkIikgJT4lCiAgZmlsdGVyKGdyZXBsKCJ0YXJnZXQwMG1vIiwgc3ViaWQpKSAlPiUKICBtdXRhdGUoc3ViaWQgPSBnc3ViKCJ0YXJnZXQuLm1vXyIsICIiLCBzdWJpZCkpICU+JQogIGNvbHVtbl90b19yb3duYW1lcygic3ViaWQiKQoKIyBhbGwgYXNzZXNzbWVudHMgb2YgOS1NT05USC1PTERTLCBSZXBzb25zZUlkIGFzIHJvd25hbWVzCmRfMDltbyA8LSBkX2FsbCAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZCIpICU+JQogIGZpbHRlcihncmVwbCgidGFyZ2V0MDltbyIsIHN1YmlkKSkgJT4lCiAgbXV0YXRlKHN1YmlkID0gZ3N1YigidGFyZ2V0Li5tb18iLCAiIiwgc3ViaWQpKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInN1YmlkIikKCiMgYWxsIGFzc2Vzc21lbnRzIG9mIDUtWUVBUi1PTERTLCBSZXBzb25zZUlkIGFzIHJvd25hbWVzCmRfNjBtbyA8LSBkX2FsbCAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZCIpICU+JQogIGZpbHRlcihncmVwbCgidGFyZ2V0NjBtbyIsIHN1YmlkKSkgJT4lCiAgbXV0YXRlKHN1YmlkID0gZ3N1YigidGFyZ2V0Li5tb18iLCAiIiwgc3ViaWQpKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInN1YmlkIikKYGBgCgoKIyBFRkE6IGFsbCB0YXJnZXRzCgpPdXIgcHJpbWFyeSBhbmFseXNpcyBpcyBhbiBleHBsb3JhdG9yeSBmYWN0b3IgYW5hbHlzaXMgKEVGQSkgY29sbGFwc2luZyBhY3Jvc3MgYWxsIDMgdGFyZ2V0IGNoYXJhY3RlcnMgKGFuZCB0cmVhdGluZyBhbiBpbmRpdmlkdWFsIHBhcnRpY2lwYW50J3MgcmVzcG9uc2VzIHRvIGVhY2ggY2hhcmFjdGVyIGFzIGlmIHRoZXkgd2VyZSBpbmRlcGVuZGVudCBkYXRhIHBvaW50cykgLSBzZWUgdGhlIHByZXJlZ2lzdHJhdGlvbiBmb3IgbW9yZSBkZXRhaWxzLiAgCgpXZSBwbGFubmVkIHRvIGV4YW1pbmUgdGhyZWUgZmFjdG9yIHJldGVudGlvbiBwcm90b2NvbHMgaW4gb3JkZXIgdG8gZGV0ZXJtaW5lIGhvdyBtYW55IGZhY3RvcnMgdG8gcmV0YWluOiBQYXJhbGxlbCBhbmFseXNpcywgbWluaW1pemluZyBCSUMsIGFuZCBhIHNldCBvZiBwcmVzZXQgY3JpdGVyaWEgb3V0bGluZWQgaW4gV2Vpc21hbiBldCBhbC4gKDIwMTcpLiBIZXJlIHdlIGxvb2sgYXQgZWFjaCBzb2x1dGlvbiBpbiB0dXJuLgoKIyMgUm90YXRpb24gY2hvaWNlcwoKV2UgcGxhbm5lZCB0byBleGFtaW5lIG9ibGltaW4tcm90YXRlZCBzb2x1dGlvbnMgKHdoaWNoIGFsbG93IGZhY3RvcnMgdG8gY29ycmVsYXRlKSwgYnV0IHlvdSBjb3VsZCBleGFtaW5lIG90aGVyIHJvdGF0aW9uIG9wdGlvbnMgYnkgc2VsZWN0aW5nIGEgZGlmZmVyZW50IHJvdGF0aW9uIHR5cGUgaGVyZS4KCmBgYHtyfQpjaG9zZW5fcm90IDwtICJvYmxpbWluIiAjIHByZXJlZ2lzdGVyZWQ6IGZhY3RvcnMgYWxsb3dlZCB0byBjb3JyZWxhdGUKIyBjaG9zZW5fcm90IDwtICJ2YXJpbWF4IiAjIG9ydGhvZ29uYWw6IGZhY3RvcnMgZm9yY2VkIG5vdCB0byBjb3JyZWxhdGUKIyBjaG9zZW5fcm90IDwtICJub25lIiAjIG5vIHJvdGF0aW9uCmBgYAoKCiMjIFBhcmFsbGVsIGFuYWx5c2lzCgojIyMgSG93IG1hbnkgZmFjdG9ycyB0byByZXRhaW4/CgpgYGB7cn0KcmV0ZW5fYWxsX1BBIDwtIGZhLnBhcmFsbGVsKGRfYWxsLCBwbG90ID0gRik7IHJldGVuX2FsbF9QQQpyZXRlbl9hbGxfcGFyIDwtIHJldGVuX2FsbF9QQSRuZmFjdApgYGAKCiMjIyBXaGF0IGFyZSB0aGVzZSBmYWN0b3JzPwoKYGBge3J9CmVmYV9hbGxfcGFyIDwtIGZhKGRfYWxsLCBuZmFjdG9ycyA9IHJldGVuX2FsbF9wYXIsIHJvdGF0ZSA9IGNob3Nlbl9yb3QsCiAgICAgICAgICAgICAgICAgIHNjb3JlcyA9ICJ0ZW5CZXJnZSIsIGltcHV0ZSA9ICJtZWRpYW4iKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LCBmaWcuYXNwID0gMS41fQpoZWF0bWFwX2Z1bihlZmFfYWxsX3BhcikgKyAKICBsYWJzKHRpdGxlID0gcGFzdGUwKCJQYXJhbGxlbCBBbmFseXNpcyAocm90YXRpb246ICIsIGNob3Nlbl9yb3QsICIpIiksCiAgICAgICBzdWJ0aXRsZSA9ICInJSB2YXIuJyBpbmRpY2F0ZXMgdGhlIGFtb3VudCBvZiBzaGFyZWQgdmFyaWFuY2UgZXhwbGFpbmVkICh0b3RhbCA9IDEwMCUpIikKYGBgCgojIyMgV2hpY2ggY2FwYWNpdGllcyBhcmUgYXR0cmlidXRlZCB0byB3aGljaCB0YXJnZXRzPwoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAwLjZ9CnNjb3Jlc3Bsb3RfZnVuKGVmYV9hbGxfcGFyLCB0YXJnZXQgPSAiYWxsIChzdHVkeSAxKSIpICsgCiAgbGFicyh0aXRsZSA9ICJQYXJhbGxlbCBBbmFseXNpcyIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSkpCmBgYAoKSGVyZSdzIGEgbXVsdGlsZXZlbCBsaW5lYXIgcmVncmVzc2lvbiBvbiB0aGVzZSBmYWN0b3Igc2NvcmVzLCB3aXRoIHJhbmRvbSBpbnRlcmNlcHRzIGFuZCBzbG9wZXMgKGZvciB0YXJnZXQgYW5kIGZhY3RvcikgYnkgcGFydGljaXBhbnQuIFRhcmdldCBpcyBjb2RlZCB3aXRoIGxpbmVhciBhbmQgcXVhZHJhdGljIGNvbnRyYXN0cywgYW5kIGZhY3RvciBpcyBlZmZlY3QtY29kZWQgZm9yIGNvbXBhcmlzb24gd2l0aCB0aGUgZ3JhbmQgbWVhbiAod2l0aCB0aGUgbGFzdCBmYWN0b3IgYXMgdGhlIGJhc2UsIC0xKToKCmBgYHtyfQplZmFfYWxsX3Bhcl9zY29yZXMgPC0gZWZhX2FsbF9wYXIkc2NvcmVzW10gJT4lCiAgZGF0YS5mcmFtZSgpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigic3ViaWQiKSAlPiUKICBtdXRhdGUodGFyZ2V0ID0gZ3N1YigiXi4qX3RhcmdldCIsICJ0YXJnZXQiLCBzdWJpZCksCiAgICAgICAgIFJlc3BvbnNlSWQgPSBnc3ViKCJfdGFyZ2V0LiokIiwgIiIsIHN1YmlkKSkgJT4lCiAgc2VsZWN0KC1zdWJpZCkgJT4lCiAgZ2F0aGVyKGZhY3Rvciwgc2NvcmUsIC10YXJnZXQsIC1SZXNwb25zZUlkKSAlPiUKICBtdXRhdGVfYXQodmFycyh0YXJnZXQsIGZhY3RvciksIGZ1bnMoZmFjdG9yKSkKCmNvbnRyYXN0cyhlZmFfYWxsX3Bhcl9zY29yZXMkdGFyZ2V0KSA8LSBjb250ci5wb2x5KDMpCmNvbnRyYXN0cyhlZmFfYWxsX3Bhcl9zY29yZXMkZmFjdG9yKSA8LSBjb250ci5zdW0ocmV0ZW5fYWxsX3BhcikKCnJfYWxsX3BhciA8LSBsbWVyKHNjb3JlIH4gdGFyZ2V0ICogZmFjdG9yICsgKHRhcmdldCArIGZhY3RvciB8IFJlc3BvbnNlSWQpLAogICAgICAgICAgICAgICAgICBlZmFfYWxsX3Bhcl9zY29yZXMpCnN1bW1hcnkocl9hbGxfcGFyLCBjb3JyID0gRikKYGBgCgpJZiB3ZSBjb25zaWRlciB0LXZhbHVlcyA+IDIgdG8gYmUgInNpZ25pZmljYW50IiBhbmQgdXNlIHRoZSBwbG90IGFib3ZlIHRvIGd1aWRlIG91ciBpbnRlcnByZXRhdGlvbiwgaGVyZSdzIHdoYXQgd2UgY29uY2x1ZGU6CgotIFtgKEludGVyY2VwdClgOiBCeSBkZWZpbml0aW9uLCBiZWNhdXNlIHdlJ3JlIHVzaW5nIGZhY3RvciBzY29yZXMsIHdoaWNoIGFyZSBzaW1pbGFyIHRvIHotc2NvcmVzLCB0aGUgaW50ZXJjZXB0IGlzIH4wLl0KLSBgdGFyZ2V0LkxgOiBPdmVyYWxsLCBtZW50YWwgY2FwYWNpdHkgYXR0cmlidXRpb25zIGluY3JlYXNlIHdpdGggdGFyZ2V0IGFnZS4KLSBgdGFyZ2V0LlFgOiBUaGlzIGluY3JlYXNlIGlzIGdlbmVyYWxseSBub24tbGluZWFyLgotIFtgZmFjdG9yMWAsIGBmYWN0b3IyYCwgLi4uOiBCeSBkZWZpbml0aW9uLCBiZWNhdXNlIHdlJ3JlIHVzaW5nIGZhY3RvciBzY29yZXMsIHdoaWNoIGFyZSBzaW1pbGFyIHRvIHotc2NvcmVzLCB0aGUgZGlmZmVyZW5jZXMgaW4gbWVhbnMgYWNyb3NzIGZhY3RvcnMgYXJlIH4wLl0KLSBgdGFyZ2V0Lkw6ZmFjdG9yMWA6IFRoZSBsaW5lYXIgaW5jcmVhc2UgaXMgbW9yZSBkcmFtYXRpYyAoc3RlZXBlciBzbG9wZSkgZm9yIE1SMSwgY29tcGFyZWQgdG8gb3RoZXIgZmFjdG9ycy4gCi0gYHRhcmdldC5ROmZhY3RvcjFgOiBUaGUgbm9ubGluZWFyaXR5IGlzIG1vcmUgZHJhbWF0aWMgKGN1cnZpZXIgYW5kL29yIGNvbmNhdmUgaW5zdGVhZCBvZiBjb252ZXggY3VydmUpIGZvciBNUjEsIGNvbXBhcmVkIHRvIG90aGVyIGZhY3RvcnMuIAotIGB0YXJnZXQuTDpmYWN0b3IyYDogVGhlIGxpbmVhciBpbmNyZWFzZSBpcyBsZXNzIGRyYW1hdGljIChzaGFsbG93ZXIgc2xvcGUpIGZvciBNUjIsIGNvbXBhcmVkIHRvIG90aGVyIGZhY3RvcnMuIAotIGB0YXJnZXQuUTpmYWN0b3IyYDogVGhlIG5vbmxpbmVhcml0eSBpcyBsZXNzIGRyYW1hdGljIChmbGF0dGVyIGN1cnZlKSBmb3IgTVIyLCBjb21wYXJlZCB0byBvdGhlciBmYWN0b3JzLiAKLSBgdGFyZ2V0Lkw6ZmFjdG9yM2A6IFRoZSBsaW5lYXIgaW5jcmVhc2UgaXMgbW9yZSBkcmFtYXRpYyAoc3RlZXBlciBzbG9wZSkgZm9yIE1SMywgY29tcGFyZWQgdG8gb3RoZXIgZmFjdG9ycy4gCi0gYHRhcmdldC5ROmZhY3RvcjNgOiBUaGUgbm9ubGluZWFyaXR5IGlzIGxlc3MgZHJhbWF0aWMgKGZsYXR0ZXIgY3VydmUpIGZvciBNUjMsIGNvbXBhcmVkIHRvIG90aGVyIGZhY3RvcnMuIAoKYGBge3IsIGZpZy53aWR0aCA9IDUsIGZpZy5hc3AgPSAxfQppdGVtc3Bsb3RfZnVuKGVmYV9hbGxfcGFyLCB0YXJnZXQgPSAiYWxsIikgKyAKICBsYWJzKHRpdGxlID0gIlBhcmFsbGVsIEFuYWx5c2lzIikKYGBgCgoKIyMgTWluaW1pemluZyBCSUMKCiMjIyBIb3cgbWFueSBmYWN0b3JzIHRvIHJldGFpbj8KCmBgYHtyfQpyZXRlbl9hbGxfdnNzIDwtIFZTUyhkX2FsbCwgcGxvdCA9IEYpOyByZXRlbl9hbGxfdnNzCnJldGVuX2FsbF9iaWMgPC0gZGF0YS5mcmFtZShyZXRlbl9hbGxfdnNzJHZzcy5zdGF0cyAlPiUKICByb3duYW1lc190b19jb2x1bW4oIm5mYWN0b3JzIikgJT4lCiAgdG9wX24oLTEsIEJJQykgJT4lCiAgc2VsZWN0KG5mYWN0b3JzKSkkbmZhY3RvcnMgJT4lIGFzLm51bWVyaWMoKQpgYGAKCiMjIyBXaGF0IGFyZSB0aGVzZSBmYWN0b3JzPwoKYGBge3J9CmVmYV9hbGxfYmljIDwtIGZhKGRfYWxsLCBuZmFjdG9ycyA9IHJldGVuX2FsbF9iaWMsIHJvdGF0ZSA9IGNob3Nlbl9yb3QsCiAgICAgICAgICAgICAgICAgIHNjb3JlcyA9ICJ0ZW5CZXJnZSIsIGltcHV0ZSA9ICJtZWRpYW4iKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LCBmaWcuYXNwID0gMS41fQpoZWF0bWFwX2Z1bihlZmFfYWxsX2JpYykgKyAKICBsYWJzKHRpdGxlID0gcGFzdGUwKCJNaW5pbWl6aW5nIEJJQyAocm90YXRpb246ICIsIGNob3Nlbl9yb3QsICIpIiksCiAgICAgICBzdWJ0aXRsZSA9ICInJSB2YXIuJyBpbmRpY2F0ZXMgdGhlIGFtb3VudCBvZiBzaGFyZWQgdmFyaWFuY2UgZXhwbGFpbmVkICh0b3RhbCA9IDEwMCUpIikKYGBgCgojIyMgV2hpY2ggY2FwYWNpdGllcyBhcmUgYXR0cmlidXRlZCB0byB3aGljaCB0YXJnZXRzPwoKYGBge3IsIGZpZy53aWR0aCA9IDUsIGZpZy5hc3AgPSAwLjZ9CnNjb3Jlc3Bsb3RfZnVuKGVmYV9hbGxfYmljLCB0YXJnZXQgPSAiYWxsIChzdHVkeSAxKSIpICsgCiAgbGFicyh0aXRsZSA9ICJNaW5pbWl6aW5nIEJJQyIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSkpCmBgYAoKSGVyZSdzIGEgbXVsdGlsZXZlbCBsaW5lYXIgcmVncmVzc2lvbiBvbiB0aGVzZSBmYWN0b3Igc2NvcmVzLCB3aXRoIHJhbmRvbSBpbnRlcmNlcHRzIGFuZCBzbG9wZXMgKGZvciB0YXJnZXQgYW5kIGZhY3RvcikgYnkgcGFydGljaXBhbnQuIFRhcmdldCBpcyBjb2RlZCB3aXRoIGxpbmVhciBhbmQgcXVhZHJhdGljIGNvbnRyYXN0cywgYW5kIGZhY3RvciBpcyBlZmZlY3QtY29kZWQgZm9yIGNvbXBhcmlzb24gd2l0aCB0aGUgZ3JhbmQgbWVhbiAod2l0aCB0aGUgbGFzdCBmYWN0b3IgYXMgdGhlIGJhc2UsIC0xKToKCmBgYHtyfQojIGVmYV9hbGxfYmljX3Njb3JlcyA8LSBlZmFfYWxsX2JpYyRzY29yZXNbXSAlPiUKIyAgIGRhdGEuZnJhbWUoKSAlPiUKIyAgIHJvd25hbWVzX3RvX2NvbHVtbigic3ViaWQiKSAlPiUKIyAgIG11dGF0ZSh0YXJnZXQgPSBnc3ViKCJeLipfdGFyZ2V0IiwgInRhcmdldCIsIHN1YmlkKSwKIyAgICAgICAgICBSZXNwb25zZUlkID0gZ3N1YigiX3RhcmdldC4qJCIsICIiLCBzdWJpZCkpICU+JQojICAgc2VsZWN0KC1zdWJpZCkgJT4lCiMgICBnYXRoZXIoZmFjdG9yLCBzY29yZSwgLXRhcmdldCwgLVJlc3BvbnNlSWQpICU+JQojICAgbXV0YXRlX2F0KHZhcnModGFyZ2V0LCBmYWN0b3IpLCBmdW5zKGZhY3RvcikpCiMgCiMgY29udHJhc3RzKGVmYV9hbGxfYmljX3Njb3JlcyR0YXJnZXQpIDwtIGNvbnRyLnBvbHkoMykKIyBjb250cmFzdHMoZWZhX2FsbF9iaWNfc2NvcmVzJGZhY3RvcikgPC0gY29udHIuc3VtKHJldGVuX2FsbF9iaWMpCiMgCiMgcl9hbGxfYmljIDwtIGxtZXIoc2NvcmUgfiB0YXJnZXQgKiBmYWN0b3IgKyAodGFyZ2V0ICsgZmFjdG9yIHwgUmVzcG9uc2VJZCksCiMgICAgICAgICAgICAgICAgICAgZWZhX2FsbF9iaWNfc2NvcmVzLAojICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsbWVyQ29udHJvbChvcHRDdHJsID0gbGlzdChtYXhmdW4gPSAxMDAwMDApKSkKIyBzdW1tYXJ5KHJfYWxsX2JpYywgY29yciA9IEYpCmBgYAoKSWYgd2UgY29uc2lkZXIgdC12YWx1ZXMgPiAyIHRvIGJlICJzaWduaWZpY2FudCIgYW5kIHVzZSB0aGUgcGxvdCBhYm92ZSB0byBndWlkZSBvdXIgaW50ZXJwcmV0YXRpb24sIGhlcmUncyB3aGF0IHdlIGNvbmNsdWRlOgoKLSBbYChJbnRlcmNlcHQpYDogQnkgZGVmaW5pdGlvbiwgYmVjYXVzZSB3ZSdyZSB1c2luZyBmYWN0b3Igc2NvcmVzLCB3aGljaCBhcmUgc2ltaWxhciB0byB6LXNjb3JlcywgdGhlIGludGVyY2VwdCBpcyB+MC5dCi0gYHRhcmdldC5MYDogT3ZlcmFsbCwgbWVudGFsIGNhcGFjaXR5IGF0dHJpYnV0aW9ucyBpbmNyZWFzZSB3aXRoIHRhcmdldCBhZ2UuCi0gYHRhcmdldC5RYDogVGhpcyBpbmNyZWFzZSBpcyAqbm90KiBnZW5lcmFsbHkgbm9uLWxpbmVhci4KLSBbYGZhY3RvcjFgLCBgZmFjdG9yMmAsIC4uLjogQnkgZGVmaW5pdGlvbiwgYmVjYXVzZSB3ZSdyZSB1c2luZyBmYWN0b3Igc2NvcmVzLCB3aGljaCBhcmUgc2ltaWxhciB0byB6LXNjb3JlcywgdGhlIGRpZmZlcmVuY2VzIGluIG1lYW5zIGFjcm9zcyBmYWN0b3JzIGFyZSB+MC5dCi0gYHRhcmdldC5MOmZhY3RvcjFgOiBUaGUgbGluZWFyIGluY3JlYXNlIGlzIG1vcmUgZHJhbWF0aWMgKHN0ZWVwZXIgc2xvcGUpIGZvciBNUjEsIGNvbXBhcmVkIHRvIG90aGVyIGZhY3RvcnMuIAotIGB0YXJnZXQuUTpmYWN0b3IxYDogVGhlIG5vbmxpbmVhcml0eSBpcyBtb3JlIGRyYW1hdGljIChjdXJ2aWVyIGFuZC9vciBjb25jYXZlIGluc3RlYWQgb2YgY29udmV4IGN1cnZlKSBmb3IgTVIxLCBjb21wYXJlZCB0byBvdGhlciBmYWN0b3JzLiAKLSBgdGFyZ2V0Lkw6ZmFjdG9yMmA6IFRoZSBsaW5lYXIgaW5jcmVhc2UgaXMgbGVzcyBkcmFtYXRpYyAoc2hhbGxvd2VyIHNsb3BlKSBmb3IgTVIyLCBjb21wYXJlZCB0byBvdGhlciBmYWN0b3JzLiAKLSBgdGFyZ2V0LlE6ZmFjdG9yMmA6IFRoZSBub25saW5lYXJpdHkgZm9yIE1SMiBpcyBjb21wYXJhYmxlIHRvIG90aGVyIGZhY3RvcnMuIAotIGB0YXJnZXQuTDpmYWN0b3IzYDogVGhlIGxpbmVhciBpbmNyZWFzZSBpcyBtb3JlIGRyYW1hdGljIChzdGVlcGVyIHNsb3BlKSBmb3IgTVIzLCBjb21wYXJlZCB0byBvdGhlciBmYWN0b3JzLiAKLSBgdGFyZ2V0LlE6ZmFjdG9yM2A6IFRoZSBub25saW5lYXJpdHkgaXMgbGVzcyBkcmFtYXRpYyAoZmxhdHRlciBjdXJ2ZSkgZm9yIE1SMywgY29tcGFyZWQgdG8gb3RoZXIgZmFjdG9ycy4gCi0gYHRhcmdldC5MOmZhY3RvcjRgOiBUaGUgbGluZWFyIGluY3JlYXNlIGlzIGxlc3MgZHJhbWF0aWMgKHNoYWxsb3dlciBzbG9wZSkgZm9yIE1SNCwgY29tcGFyZWQgdG8gb3RoZXIgZmFjdG9ycy4gCi0gYHRhcmdldC5ROmZhY3RvcjRgOiBUaGUgbm9ubGluZWFyaXR5IGlzIG1vcmUgZHJhbWF0aWMgKGN1cnZpZXIgYW5kL29yIGNvbmNhbnZlIGluc3RlYWQgb2YgY29udmV4IGN1cnZlKSBmb3IgTVI0LCBjb21wYXJlZCB0byBvdGhlciBmYWN0b3JzLiAKLSBgdGFyZ2V0Lkw6ZmFjdG9yNWA6IFRoZSBsaW5lYXIgaW5jcmVhc2UgaXMgbW9yZSBkcmFtYXRpYyAoc3RlZXBlciBzbG9wZSkgZm9yIE1SNSwgY29tcGFyZWQgdG8gb3RoZXIgZmFjdG9ycy4gCi0gYHRhcmdldC5ROmZhY3RvcjVgOiBUaGUgbm9ubGluZWFyaXR5IGlzIGxlc3MgZHJhbWF0aWMgKGZsYXR0ZXIgY3VydmUpIGZvciBNUjUsIGNvbXBhcmVkIHRvIG90aGVyIGZhY3RvcnMuIAoKYGBge3IsIGZpZy53aWR0aCA9IDUsIGZpZy5hc3AgPSAxfQppdGVtc3Bsb3RfZnVuKGVmYV9hbGxfYmljLCB0YXJnZXQgPSAiYWxsIikgKyAKICBsYWJzKHRpdGxlID0gIk1pbmltaXppbmcgQklDIikKYGBgCgoKIyMgUHJlc2V0IHJldGVudGlvbiBjcml0ZXJpYQoKIyMjIEhvdyBtYW55IGZhY3RvcnMgdG8gcmV0YWluPwoKYGBge3J9CnJldGVuX2FsbF9rIDwtIHJldGVuX2Z1bihkX2FsbCwgcm90X3R5cGUgPSBjaG9zZW5fcm90KQpwcmludChwYXN0ZSgiUHJlc2V0IGNyaXRlcmlhIHN1Z2dlc3QgcmV0YWluaW5nIiwgcmV0ZW5fYWxsX2ssICJmYWN0b3JzIikpCmBgYAoKIyMjIFdoYXQgYXJlIHRoZXNlIGZhY3RvcnM/CgpgYGB7cn0KZWZhX2FsbF9rIDwtIGZhKGRfYWxsLCBuZmFjdG9ycyA9IHJldGVuX2FsbF9rLCByb3RhdGUgPSBjaG9zZW5fcm90LAogICAgICAgICAgICAgICAgICBzY29yZXMgPSAidGVuQmVyZ2UiLCBpbXB1dGUgPSAibWVkaWFuIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNCwgZmlnLmFzcCA9IDEuNX0KaGVhdG1hcF9mdW4oZWZhX2FsbF9rKSArIAogIGxhYnModGl0bGUgPSBwYXN0ZTAoIlByZXNldCBjcml0ZXJpYSAocm90YXRpb246ICIsIGNob3Nlbl9yb3QsICIpIiksCiAgICAgICBzdWJ0aXRsZSA9ICInJSB2YXIuJyBpbmRpY2F0ZXMgdGhlIGFtb3VudCBvZiBzaGFyZWQgdmFyaWFuY2UgZXhwbGFpbmVkICh0b3RhbCA9IDEwMCUpIikKYGBgCgojIyMgV2hpY2ggY2FwYWNpdGllcyBhcmUgYXR0cmlidXRlZCB0byB3aGljaCB0YXJnZXRzPwoKYGBge3J9CnNjb3Jlc3Bsb3RfZnVuKGVmYV9hbGxfaywgdGFyZ2V0ID0gImFsbCAoc3R1ZHkgMSkiKSArIAogIGxhYnModGl0bGUgPSAiUHJlc2V0IGZhY3RvciByZXRlbnRpb24gY3JpdGVyaWEgKFdlaXNtYW4gZXQgYWwuLCAyMDE3KSIpCmBgYAoKSGVyZSdzIGEgbXVsdGlsZXZlbCBsaW5lYXIgcmVncmVzc2lvbiBvbiB0aGVzZSBmYWN0b3Igc2NvcmVzLCB3aXRoIHJhbmRvbSBpbnRlcmNlcHRzIGFuZCBzbG9wZXMgKGZvciB0YXJnZXQgYW5kIGZhY3RvcikgYnkgcGFydGljaXBhbnQuIFRhcmdldCBpcyBjb2RlZCB3aXRoIGxpbmVhciBhbmQgcXVhZHJhdGljIGNvbnRyYXN0cywgYW5kIGZhY3RvciBpcyBlZmZlY3QtY29kZWQgZm9yIGNvbXBhcmlzb24gd2l0aCB0aGUgZ3JhbmQgbWVhbiAod2l0aCB0aGUgbGFzdCBmYWN0b3IgYXMgdGhlIGJhc2UsIC0xKToKCmBgYHtyfQplZmFfYWxsX2tfc2NvcmVzIDwtIGVmYV9hbGxfayRzY29yZXNbXSAlPiUKICBkYXRhLmZyYW1lKCkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZCIpICU+JQogIG11dGF0ZSh0YXJnZXQgPSBnc3ViKCJeLipfdGFyZ2V0IiwgInRhcmdldCIsIHN1YmlkKSwKICAgICAgICAgUmVzcG9uc2VJZCA9IGdzdWIoIl90YXJnZXQuKiQiLCAiIiwgc3ViaWQpKSAlPiUKICBzZWxlY3QoLXN1YmlkKSAlPiUKICBnYXRoZXIoZmFjdG9yLCBzY29yZSwgLXRhcmdldCwgLVJlc3BvbnNlSWQpICU+JQogIG11dGF0ZV9hdCh2YXJzKHRhcmdldCwgZmFjdG9yKSwgZnVucyhmYWN0b3IpKQoKY29udHJhc3RzKGVmYV9hbGxfa19zY29yZXMkdGFyZ2V0KSA8LSBjb250ci5wb2x5KDMpCmNvbnRyYXN0cyhlZmFfYWxsX2tfc2NvcmVzJGZhY3RvcikgPC0gY29udHIuc3VtKHJldGVuX2FsbF9rKQoKcl9hbGxfayA8LSBsbWVyKHNjb3JlIH4gdGFyZ2V0ICogZmFjdG9yICsgKHRhcmdldCArIGZhY3RvciB8IFJlc3BvbnNlSWQpLAogICAgICAgICAgICAgICAgZWZhX2FsbF9rX3Njb3JlcykKc3VtbWFyeShyX2FsbF9rLCBjb3JyID0gRikKYGBgCgoqKlRoZXJlIGFyZSBzb21lIHByb2JsZW1zIHdpdGggdGhpcyBtb2RlbCB0aGF0IEkgaGF2ZW4ndCBhZGRyZXNzZWQqKiAtIHNlZSB3YXJuaW5ncyBhYm92ZS4gSWdub3JpbmcgdGhlbSBmb3Igbm93Li4uIAoKSWYgd2UgY29uc2lkZXIgdC12YWx1ZXMgPiAyIHRvIGJlICJzaWduaWZpY2FudCIgYW5kIHVzZSB0aGUgcGxvdCBhYm92ZSB0byBndWlkZSBvdXIgaW50ZXJwcmV0YXRpb24sIGhlcmUncyB3aGF0IHdlIGNvbmNsdWRlOgoKLSBbYChJbnRlcmNlcHQpYDogQnkgZGVmaW5pdGlvbiwgYmVjYXVzZSB3ZSdyZSB1c2luZyBmYWN0b3Igc2NvcmVzLCB3aGljaCBhcmUgc2ltaWxhciB0byB6LXNjb3JlcywgdGhlIGludGVyY2VwdCBpcyB+MC5dCi0gYHRhcmdldC5MYDogT3ZlcmFsbCwgbWVudGFsIGNhcGFjaXR5IGF0dHJpYnV0aW9ucyBpbmNyZWFzZSB3aXRoIHRhcmdldCBhZ2UuCi0gYHRhcmdldC5RYDogVGhpcyBpbmNyZWFzZSBpcyBnZW5lcmFsbHkgbm9uLWxpbmVhci4KLSBbYGZhY3RvcjFgOiBCeSBkZWZpbml0aW9uLCBiZWNhdXNlIHdlJ3JlIHVzaW5nIGZhY3RvciBzY29yZXMsIHdoaWNoIGFyZSBzaW1pbGFyIHRvIHotc2NvcmVzLCB0aGUgZGlmZmVyZW5jZXMgaW4gbWVhbnMgYWNyb3NzIGZhY3RvcnMgYXJlIH4wLl0KLSBgdGFyZ2V0Lkw6ZmFjdG9yMWA6IFRoZSBsaW5lYXIgaW5jcmVhc2UgaXMgbW9yZSBkcmFtYXRpYyAoc3RlZXBlciBzbG9wZSkgZm9yIE1SMSwgY29tcGFyZWQgdG8gb3RoZXIgZmFjdG9ycy4gCi0gYHRhcmdldC5ROmZhY3RvcjFgOiBUaGUgbm9ubGluZWFyaXR5IGlzIG1vcmUgZHJhbWF0aWMgKGN1cnZpZXIgYW5kL29yIGNvbmNhdmUgaW5zdGVhZCBvZiBjb252ZXggY3VydmUpIGZvciBNUjEsIGNvbXBhcmVkIHRvIG90aGVyIGZhY3RvcnMuIAoKYGBge3IsIGZpZy53aWR0aCA9IDUsIGZpZy5hc3AgPSAxfQppdGVtc3Bsb3RfZnVuKGVmYV9hbGxfaywgdGFyZ2V0ID0gImFsbCIpICsgCiAgbGFicyh0aXRsZSA9ICJQcmVzZXQgZmFjdG9yIHJldGVudGlvbiBjcml0ZXJpYSAoV2Vpc21hbiBldCBhbC4sIDIwMTcpIikKYGBgCgoKIyBFRkE6IG5ld2Jvcm5zCgpXaGF0IGhhcHBlbnMgaWYgd2UgbGltaXQgb3Vyc2VsdmVzIHRvIGFzc2Vzc21lbnRzIG9mIG5ld2Jvcm5zJyBtZW50YWwgY2FwYWNpdGllcz8KCiMjIFBhcmFsbGVsIGFuYWx5c2lzCgojIyMgSG93IG1hbnkgZmFjdG9ycyB0byByZXRhaW4/CgpgYGB7cn0KcmV0ZW5fMDBtb19QQSA8LSBmYS5wYXJhbGxlbChkXzAwbW8sIHBsb3QgPSBGKTsgcmV0ZW5fMDBtb19QQQpyZXRlbl8wMG1vX3BhciA8LSByZXRlbl8wMG1vX1BBJG5mYWN0CmBgYAoKIyMjIFdoYXQgYXJlIHRoZXNlIGZhY3RvcnM/CgpgYGB7cn0KZWZhXzAwbW9fcGFyIDwtIGZhKGRfMDBtbywgbmZhY3RvcnMgPSByZXRlbl8wMG1vX3Bhciwgcm90YXRlID0gY2hvc2VuX3JvdCwKICAgICAgICAgICAgICAgICAgc2NvcmVzID0gInRlbkJlcmdlIiwgaW1wdXRlID0gIm1lZGlhbiIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAxLjV9CmhlYXRtYXBfZnVuKGVmYV8wMG1vX3BhcikgKyAKICBsYWJzKHRpdGxlID0gcGFzdGUwKCJQYXJhbGxlbCBBbmFseXNpcyAocm90YXRpb246ICIsIGNob3Nlbl9yb3QsICIpIiksCiAgICAgICBzdWJ0aXRsZSA9ICInJSB2YXIuJyBpbmRpY2F0ZXMgdGhlIGFtb3VudCBvZiBzaGFyZWQgdmFyaWFuY2UgZXhwbGFpbmVkICh0b3RhbCA9IDEwMCUpIikKYGBgCgojIyMgV2hpY2ggY2FwYWNpdGllcyBhcmUgYXR0cmlidXRlZCB0byBuZXdib3Jucz8KCmBgYHtyLCBmaWcud2lkdGggPSAzLjUsIGZpZy5hc3AgPSAyfQppdGVtc3Bsb3RfZnVuKGVmYV8wMG1vX3BhciwgdGFyZ2V0ID0gIm5ld2Jvcm5zIikgKyAKICBsYWJzKHRpdGxlID0gIlBhcmFsbGVsIEFuYWx5c2lzIikKYGBgCgoKIyMgTWluaW1pemluZyBCSUMKCiMjIyBIb3cgbWFueSBmYWN0b3JzIHRvIHJldGFpbj8KCmBgYHtyfQpyZXRlbl8wMG1vX3ZzcyA8LSBWU1MoZF8wMG1vLCBwbG90ID0gRik7IHJldGVuXzAwbW9fdnNzCnJldGVuXzAwbW9fYmljIDwtIGRhdGEuZnJhbWUocmV0ZW5fMDBtb192c3MkdnNzLnN0YXRzICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigibmZhY3RvcnMiKSAlPiUKICB0b3BfbigtMSwgQklDKSAlPiUKICBzZWxlY3QobmZhY3RvcnMpKSRuZmFjdG9ycyAlPiUgYXMubnVtZXJpYygpCmBgYAoKIyMjIFdoYXQgYXJlIHRoZXNlIGZhY3RvcnM/CgpgYGB7cn0KZWZhXzAwbW9fYmljIDwtIGZhKGRfMDBtbywgbmZhY3RvcnMgPSByZXRlbl8wMG1vX2JpYywgcm90YXRlID0gY2hvc2VuX3JvdCwKICAgICAgICAgICAgICAgICAgIHNjb3JlcyA9ICJ0ZW5CZXJnZSIsIGltcHV0ZSA9ICJtZWRpYW4iKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LCBmaWcuYXNwID0gMS41fQpoZWF0bWFwX2Z1bihlZmFfMDBtb19iaWMpICsgCiAgbGFicyh0aXRsZSA9IHBhc3RlMCgiTWluaW1pemluZyBCSUMgKHJvdGF0aW9uOiAiLCBjaG9zZW5fcm90LCAiKSIpLAogICAgICAgc3VidGl0bGUgPSAiJyUgdmFyLicgaW5kaWNhdGVzIHRoZSBhbW91bnQgb2Ygc2hhcmVkIHZhcmlhbmNlIGV4cGxhaW5lZCAodG90YWwgPSAxMDAlKSIpCmBgYAoKIyMjIFdoaWNoIGNhcGFjaXRpZXMgYXJlIGF0dHJpYnV0ZWQgdG8gbmV3Ym9ybnM/CgpgYGB7ciwgZmlnLndpZHRoID0gMy41LCBmaWcuYXNwID0gMn0KaXRlbXNwbG90X2Z1bihlZmFfMDBtb19iaWMsIHRhcmdldCA9ICJuZXdib3JucyIpICsgCiAgbGFicyh0aXRsZSA9ICJNaW5pbWl6aW5nIEJJQyIpCmBgYAoKCiMjIFByZXNldCByZXRlbnRpb24gY3JpdGVyaWEKCiMjIyBIb3cgbWFueSBmYWN0b3JzIHRvIHJldGFpbj8KCmBgYHtyfQpyZXRlbl8wMG1vX2sgPC0gcmV0ZW5fZnVuKGRfMDBtbywgcm90X3R5cGUgPSBjaG9zZW5fcm90KQpwcmludChwYXN0ZSgiUHJlc2V0IGNyaXRlcmlhIHN1Z2dlc3QgcmV0YWluaW5nIiwgcmV0ZW5fMDBtb19rLCAiZmFjdG9ycyIpKQpgYGAKCiMjIyBXaGF0IGFyZSB0aGVzZSBmYWN0b3JzPwoKYGBge3J9CmVmYV8wMG1vX2sgPC0gZmEoZF8wMG1vLCBuZmFjdG9ycyA9IHJldGVuXzAwbW9faywgcm90YXRlID0gY2hvc2VuX3JvdCwKICAgICAgICAgICAgICAgICBzY29yZXMgPSAidGVuQmVyZ2UiLCBpbXB1dGUgPSAibWVkaWFuIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNCwgZmlnLmFzcCA9IDEuNX0KaGVhdG1hcF9mdW4oZWZhXzAwbW9faykgKyAKICBsYWJzKHRpdGxlID0gcGFzdGUwKCJQcmVzZXQgY3JpdGVyaWEgKHJvdGF0aW9uOiAiLCBjaG9zZW5fcm90LCAiKSIpLAogICAgICAgc3VidGl0bGUgPSAiJyUgdmFyLicgaW5kaWNhdGVzIHRoZSBhbW91bnQgb2Ygc2hhcmVkIHZhcmlhbmNlIGV4cGxhaW5lZCAodG90YWwgPSAxMDAlKSIpCmBgYAoKIyMjIFdoaWNoIGNhcGFjaXRpZXMgYXJlIGF0dHJpYnV0ZWQgdG8gbmV3Ym9ybnM/CgpgYGB7ciwgZmlnLndpZHRoID0gMy41LCBmaWcuYXNwID0gMn0KaXRlbXNwbG90X2Z1bihlZmFfMDBtb19rLCB0YXJnZXQgPSAibmV3Ym9ybnMiKSArIAogIGxhYnModGl0bGUgPSAiUHJlc2V0IGZhY3RvciByZXRlbnRpb24gY3JpdGVyaWFcbihXZWlzbWFuIGV0IGFsLiwgMjAxNykiKQpgYGAKCgojIEVGQTogOS1tb250aC1vbGRzCgpXaGF0IGhhcHBlbnMgaWYgd2UgbGltaXQgb3Vyc2VsdmVzIHRvIGFzc2Vzc21lbnRzIG9mIDktbW9udGgtb2xkcycgbWVudGFsIGNhcGFjaXRpZXM/CgojIyBQYXJhbGxlbCBhbmFseXNpcwoKIyMjIEhvdyBtYW55IGZhY3RvcnMgdG8gcmV0YWluPwoKYGBge3J9CnJldGVuXzA5bW9fUEEgPC0gZmEucGFyYWxsZWwoZF8wOW1vLCBwbG90ID0gRik7IHJldGVuXzA5bW9fUEEKcmV0ZW5fMDltb19wYXIgPC0gcmV0ZW5fMDltb19QQSRuZmFjdApgYGAKCiMjIyBXaGF0IGFyZSB0aGVzZSBmYWN0b3JzPwoKYGBge3J9CmVmYV8wOW1vX3BhciA8LSBmYShkXzA5bW8sIG5mYWN0b3JzID0gcmV0ZW5fMDltb19wYXIsIHJvdGF0ZSA9IGNob3Nlbl9yb3QsCiAgICAgICAgICAgICAgICAgICBzY29yZXMgPSAidGVuQmVyZ2UiLCBpbXB1dGUgPSAibWVkaWFuIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNCwgZmlnLmFzcCA9IDEuNX0KaGVhdG1hcF9mdW4oZWZhXzA5bW9fcGFyKSArIAogIGxhYnModGl0bGUgPSBwYXN0ZTAoIlBhcmFsbGVsIGFuYWx5c2lzIChyb3RhdGlvbjogIiwgY2hvc2VuX3JvdCwgIikiKSwKICAgICAgIHN1YnRpdGxlID0gIiclIHZhci4nIGluZGljYXRlcyB0aGUgYW1vdW50IG9mIHNoYXJlZCB2YXJpYW5jZSBleHBsYWluZWQgKHRvdGFsID0gMTAwJSkiKQpgYGAKCgojIyMgV2hpY2ggY2FwYWNpdGllcyBhcmUgYXR0cmlidXRlZCB0byA5LW1vbnRoLW9sZHM/CgpgYGB7ciwgZmlnLndpZHRoID0gMy41LCBmaWcuYXNwID0gMn0KaXRlbXNwbG90X2Z1bihlZmFfMDltb19wYXIsIHRhcmdldCA9ICI5LW1vbnRoLW9sZHMiKSArIAogIGxhYnModGl0bGUgPSAiUGFyYWxsZWwgQW5hbHlzaXMiKQpgYGAKCgojIyBNaW5pbWl6aW5nIEJJQwoKIyMjIEhvdyBtYW55IGZhY3RvcnMgdG8gcmV0YWluPwoKYGBge3J9CnJldGVuXzA5bW9fdnNzIDwtIFZTUyhkXzA5bW8sIHBsb3QgPSBGKTsgcmV0ZW5fMDltb192c3MKcmV0ZW5fMDltb19iaWMgPC0gZGF0YS5mcmFtZShyZXRlbl8wOW1vX3ZzcyR2c3Muc3RhdHMgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJuZmFjdG9ycyIpICU+JQogIHRvcF9uKC0xLCBCSUMpICU+JQogIHNlbGVjdChuZmFjdG9ycykpJG5mYWN0b3JzICU+JSBhcy5udW1lcmljKCkKYGBgCgojIyMgV2hhdCBhcmUgdGhlc2UgZmFjdG9ycz8KCmBgYHtyfQplZmFfMDltb19iaWMgPC0gZmEoZF8wOW1vLCBuZmFjdG9ycyA9IHJldGVuXzA5bW9fYmljLCByb3RhdGUgPSBjaG9zZW5fcm90LAogICAgICAgICAgICAgICAgICAgc2NvcmVzID0gInRlbkJlcmdlIiwgaW1wdXRlID0gIm1lZGlhbiIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAxLjV9CmhlYXRtYXBfZnVuKGVmYV8wOW1vX2JpYykgKyAKICBsYWJzKHRpdGxlID0gcGFzdGUwKCJNaW5pbWl6aW5nIEJJQyAocm90YXRpb246ICIsIGNob3Nlbl9yb3QsICIpIiksCiAgICAgICBzdWJ0aXRsZSA9ICInJSB2YXIuJyBpbmRpY2F0ZXMgdGhlIGFtb3VudCBvZiBzaGFyZWQgdmFyaWFuY2UgZXhwbGFpbmVkICh0b3RhbCA9IDEwMCUpIikKYGBgCgojIyMgV2hpY2ggY2FwYWNpdGllcyBhcmUgYXR0cmlidXRlZCB0byA5LW1vbnRoLW9sZHM/CgpgYGB7ciwgZmlnLndpZHRoID0gMy41LCBmaWcuYXNwID0gMn0KaXRlbXNwbG90X2Z1bihlZmFfMDltb19iaWMsIHRhcmdldCA9ICI5LW1vbnRoLW9sZHMiKSArIAogIGxhYnModGl0bGUgPSAiTWluaW1pemluZyBCSUMiKQpgYGAKCgojIyBQcmVzZXQgcmV0ZW50aW9uIGNyaXRlcmlhCgojIyMgSG93IG1hbnkgZmFjdG9ycyB0byByZXRhaW4/CgpgYGB7cn0KcmV0ZW5fMDltb19rIDwtIHJldGVuX2Z1bihkXzA5bW8sIHJvdF90eXBlID0gY2hvc2VuX3JvdCkKcHJpbnQocGFzdGUoIlByZXNldCBjcml0ZXJpYSBzdWdnZXN0IHJldGFpbmluZyIsIHJldGVuXzA5bW9faywgImZhY3RvcnMiKSkKYGBgCgojIyMgV2hhdCBhcmUgdGhlc2UgZmFjdG9ycz8KCmBgYHtyfQplZmFfMDltb19rIDwtIGZhKGRfMDltbywgbmZhY3RvcnMgPSByZXRlbl8wOW1vX2ssIHJvdGF0ZSA9IGNob3Nlbl9yb3QsCiAgICAgICAgICAgICAgICAgc2NvcmVzID0gInRlbkJlcmdlIiwgaW1wdXRlID0gIm1lZGlhbiIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAxLjV9CmhlYXRtYXBfZnVuKGVmYV8wOW1vX2spICsgCiAgbGFicyh0aXRsZSA9IHBhc3RlMCgiUHJlc2V0IGNyaXRlcmlhIChyb3RhdGlvbjogIiwgY2hvc2VuX3JvdCwgIikiKSwKICAgICAgIHN1YnRpdGxlID0gIiclIHZhci4nIGluZGljYXRlcyB0aGUgYW1vdW50IG9mIHNoYXJlZCB2YXJpYW5jZSBleHBsYWluZWQgKHRvdGFsID0gMTAwJSkiKQpgYGAKCiMjIyBXaGljaCBjYXBhY2l0aWVzIGFyZSBhdHRyaWJ1dGVkIHRvIDktbW9udGgtb2xkcz8KCmBgYHtyLCBmaWcud2lkdGggPSAzLjUsIGZpZy5hc3AgPSAyfQppdGVtc3Bsb3RfZnVuKGVmYV8wOW1vX2ssIHRhcmdldCA9ICI5LW1vbnRoLW9sZHMiKSArIAogIGxhYnModGl0bGUgPSAiUHJlc2V0IGZhY3RvciByZXRlbnRpb24gY3JpdGVyaWFcbihXZWlzbWFuIGV0IGFsLiwgMjAxNykiKQpgYGAKCgojIEVGQTogNS15ZWFyLW9sZHMKCldoYXQgaGFwcGVucyBpZiB3ZSBsaW1pdCBvdXJzZWx2ZXMgdG8gYXNzZXNzbWVudHMgb2YgNS15ZWFyLW9sZHMnIG1lbnRhbCBjYXBhY2l0aWVzPwoKIyMgUGFyYWxsZWwgYW5hbHlzaXMKCiMjIyBIb3cgbWFueSBmYWN0b3JzIHRvIHJldGFpbj8KCmBgYHtyfQpyZXRlbl82MG1vX1BBIDwtIGZhLnBhcmFsbGVsKGRfNjBtbywgcGxvdCA9IEYpOyByZXRlbl82MG1vX1BBCnJldGVuXzYwbW9fcGFyIDwtIHJldGVuXzYwbW9fUEEkbmZhY3QKYGBgCgojIyMgV2hhdCBhcmUgdGhlc2UgZmFjdG9ycz8KCmBgYHtyfQplZmFfNjBtb19wYXIgPC0gZmEoZF82MG1vLCBuZmFjdG9ycyA9IHJldGVuXzYwbW9fcGFyLCByb3RhdGUgPSBjaG9zZW5fcm90LAogICAgICAgICAgICAgICAgICAgc2NvcmVzID0gInRlbkJlcmdlIiwgaW1wdXRlID0gIm1lZGlhbiIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAxLjV9CmhlYXRtYXBfZnVuKGVmYV82MG1vX3BhcikgKyAKICBsYWJzKHRpdGxlID0gcGFzdGUwKCJQYXJhbGxlbCBhbmFseXNpcyAocm90YXRpb246ICIsIGNob3Nlbl9yb3QsICIpIiksCiAgICAgICBzdWJ0aXRsZSA9ICInJSB2YXIuJyBpbmRpY2F0ZXMgdGhlIGFtb3VudCBvZiBzaGFyZWQgdmFyaWFuY2UgZXhwbGFpbmVkICh0b3RhbCA9IDEwMCUpIikKYGBgCgojIyMgV2hpY2ggY2FwYWNpdGllcyBhcmUgYXR0cmlidXRlZCB0byA1LXllYXItb2xkcz8KCmBgYHtyLCBmaWcud2lkdGggPSAzLjUsIGZpZy5hc3AgPSAyfQppdGVtc3Bsb3RfZnVuKGVmYV82MG1vX3BhciwgdGFyZ2V0ID0gIjUteWVhci1vbGRzIikgKyAKICBsYWJzKHRpdGxlID0gIlBhcmFsbGVsIEFuYWx5c2lzIikKYGBgCgoKIyMgTWluaW1pemluZyBCSUMKCiMjIyBIb3cgbWFueSBmYWN0b3JzIHRvIHJldGFpbj8KCmBgYHtyfQpyZXRlbl82MG1vX3ZzcyA8LSBWU1MoZF82MG1vLCBwbG90ID0gRik7IHJldGVuXzYwbW9fdnNzCnJldGVuXzYwbW9fYmljIDwtIGRhdGEuZnJhbWUocmV0ZW5fNjBtb192c3MkdnNzLnN0YXRzICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigibmZhY3RvcnMiKSAlPiUKICB0b3BfbigtMSwgQklDKSAlPiUKICBzZWxlY3QobmZhY3RvcnMpKSRuZmFjdG9ycyAlPiUgYXMubnVtZXJpYygpCmBgYAoKIyMjIFdoYXQgYXJlIHRoZXNlIGZhY3RvcnM/CgpgYGB7cn0KZWZhXzYwbW9fYmljIDwtIGZhKGRfNjBtbywgbmZhY3RvcnMgPSByZXRlbl82MG1vX2JpYywgcm90YXRlID0gY2hvc2VuX3JvdCwKICAgICAgICAgICAgICAgICAgIHNjb3JlcyA9ICJ0ZW5CZXJnZSIsIGltcHV0ZSA9ICJtZWRpYW4iKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LCBmaWcuYXNwID0gMS41fQpoZWF0bWFwX2Z1bihlZmFfNjBtb19iaWMpICsgCiAgbGFicyh0aXRsZSA9IHBhc3RlMCgiTWluaW1pemluZyBCSUMgKHJvdGF0aW9uOiAiLCBjaG9zZW5fcm90LCAiKSIpLAogICAgICAgc3VidGl0bGUgPSAiJyUgdmFyLicgaW5kaWNhdGVzIHRoZSBhbW91bnQgb2Ygc2hhcmVkIHZhcmlhbmNlIGV4cGxhaW5lZCAodG90YWwgPSAxMDAlKSIpCmBgYAoKIyMjIFdoaWNoIGNhcGFjaXRpZXMgYXJlIGF0dHJpYnV0ZWQgdG8gNS15ZWFyLW9sZHM/CgpgYGB7ciwgZmlnLndpZHRoID0gMy41LCBmaWcuYXNwID0gMn0KaXRlbXNwbG90X2Z1bihlZmFfNjBtb19iaWMsIHRhcmdldCA9ICI1LXllYXItb2xkcyIpICsgCiAgbGFicyh0aXRsZSA9ICJNaW5pbWl6aW5nIEJJQyIpCmBgYAoKCiMjIFByZXNldCByZXRlbnRpb24gY3JpdGVyaWEKCiMjIyBIb3cgbWFueSBmYWN0b3JzIHRvIHJldGFpbj8KCmBgYHtyfQpyZXRlbl82MG1vX2sgPC0gcmV0ZW5fZnVuKGRfNjBtbywgcm90X3R5cGUgPSBjaG9zZW5fcm90KQpwcmludChwYXN0ZSgiUHJlc2V0IGNyaXRlcmlhIHN1Z2dlc3QgcmV0YWluaW5nIiwgcmV0ZW5fNjBtb19rLCAiZmFjdG9ycyIpKQpgYGAKCiMjIyBXaGF0IGFyZSB0aGVzZSBmYWN0b3JzPwoKYGBge3J9CmVmYV82MG1vX2sgPC0gZmEoZF82MG1vLCBuZmFjdG9ycyA9IHJldGVuXzYwbW9faywgcm90YXRlID0gY2hvc2VuX3JvdCwKICAgICAgICAgICAgICAgICBzY29yZXMgPSAidGVuQmVyZ2UiLCBpbXB1dGUgPSAibWVkaWFuIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNCwgZmlnLmFzcCA9IDEuNX0KaGVhdG1hcF9mdW4oZWZhXzYwbW9faykgKyAKICBsYWJzKHRpdGxlID0gcGFzdGUwKCJQcmVzZXQgY3JpdGVyaWEgKHJvdGF0aW9uOiAiLCBjaG9zZW5fcm90LCAiKSIpLAogICAgICAgc3VidGl0bGUgPSAiJyUgdmFyLicgaW5kaWNhdGVzIHRoZSBhbW91bnQgb2Ygc2hhcmVkIHZhcmlhbmNlIGV4cGxhaW5lZCAodG90YWwgPSAxMDAlKSIpCmBgYAoKIyMjIFdoaWNoIGNhcGFjaXRpZXMgYXJlIGF0dHJpYnV0ZWQgdG8gNS15ZWFyLW9sZHM/CgpgYGB7ciwgZmlnLndpZHRoID0gMy41LCBmaWcuYXNwID0gMn0KaXRlbXNwbG90X2Z1bihlZmFfNjBtb19rLCB0YXJnZXQgPSAiNS15ZWFyLW9sZHMiKSArIAogIGxhYnModGl0bGUgPSAiUHJlc2V0IGZhY3RvciByZXRlbnRpb24gY3JpdGVyaWFcbihXZWlzbWFuIGV0IGFsLiwgMjAxNykiKQpgYGAKCgojIERlbW9ncmFwaGljcwoKYGBge3J9CmdncGxvdChkX2RlbW8sIGFlcyh4ID0gRHVyYXRpb24vNjApKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IG1lZGlhbihkX2RlbW8kRHVyYXRpb24vNjApLCBjb2xvciA9ICJibHVlIiwgbHR5ID0gMikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwMDAsIDQpKSArCiAgbGFicyh0aXRsZSA9ICJEdXJhdGlvbiBvZiBzdHVkeSAoYWNjb3JkaW5nIHRvIFF1YWx0cmljcykiLAogICAgICAgc3VidGl0bGUgPSAiQmx1ZSBkb3R0ZWQgbGluZSBtYXJrcyBtZWRpYW4iLAogICAgICAgeCA9ICJEdXJhdGlvbiAoaW4gbWludXRlcykiLAogICAgICAgeSA9ICJOdW1iZXIgb2YgcGFydGljaXBhbnRzIikKYGBgCgpgYGB7cn0KZ2dwbG90KGRfZGVtbywgYWVzKHggPSBBZ2UpKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IG1lZGlhbihkX2RlbW8kQWdlKSwgY29sb3IgPSAiYmx1ZSIsIGx0eSA9IDIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMDAwLCA0KSkgKwogIGxhYnModGl0bGUgPSAiUGFydGljcGlhbnQgYWdlIChzZWxmLXJlcG9ydGVkKSIsCiAgICAgICBzdWJ0aXRsZSA9ICJCbHVlIGRvdHRlZCBsaW5lIG1hcmtzIG1lZGlhbiIsCiAgICAgICB4ID0gIkFnZSAoaW4geWVhcnMpIiwKICAgICAgIHkgPSAiTnVtYmVyIG9mIHBhcnRpY2lwYW50cyIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDMsIGZpZy5hc3AgPSAxfQplZmFfYWxsX3Bhcl9zY29yZXMgJT4lCiAgbXV0YXRlKFJlc3BvbnNlSWQgPSBhcy5jaGFyYWN0ZXIoUmVzcG9uc2VJZCkpICU+JQogIGxlZnRfam9pbihkX2RlbW8gJT4lIAogICAgICAgICAgICAgIGRpc3RpbmN0KFJlc3BvbnNlSWQsIEFnZSkgJT4lIAogICAgICAgICAgICAgIG11dGF0ZShSZXNwb25zZUlkID0gYXMuY2hhcmFjdGVyKFJlc3BvbnNlSWQpKSkgJT4lCiAgbXV0YXRlKGZhY3RvciA9IGZhY3RvcihmYWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNUjEiLCAiTVIzIiwgIk1SMiIsICJNUjQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoImNvZ25pdGlvbiAmIGNvbnRyb2wiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBvc2l0aXZlICYgc29jaWFsIGVtb3Rpb25zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJvZGlseSBzZW5zYXRpb25zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5lZ2F0aXZlIGVtb3Rpb25zIikpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBBZ2UsIHkgPSBzY29yZSkpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsdHkgPSAyKSArCiAgZmFjZXRfZ3JpZChmYWN0b3IgfiB0YXJnZXQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9wb2ludChhbHBoYSA9IDAuMDUpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDEwLCAxKSkKYGBgCgpgYGB7cn0KZ2dwbG90KGRfZGVtbywgYWVzKHggPSBHZW5kZXJTZXgpKSArIAogIGdlb21fYmFyKCkgKwogIGxhYnModGl0bGUgPSAiUGFydGljcGlhbnQgZ2VuZGVyL3NleCAoc2VsZi1yZXBvcnRlZCkiLAogICAgICAgeCA9ICJHZW5kZXIvc2V4IiwKICAgICAgIHkgPSAiTnVtYmVyIG9mIHBhcnRpY2lwYW50cyIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDMsIGZpZy5hc3AgPSAxfQplZmFfYWxsX3Bhcl9zY29yZXMgJT4lCiAgbXV0YXRlKFJlc3BvbnNlSWQgPSBhcy5jaGFyYWN0ZXIoUmVzcG9uc2VJZCkpICU+JQogIGxlZnRfam9pbihkX2RlbW8gJT4lIAogICAgICAgICAgICAgIGRpc3RpbmN0KFJlc3BvbnNlSWQsIEdlbmRlclNleCkgJT4lIAogICAgICAgICAgICAgIG11dGF0ZShSZXNwb25zZUlkID0gYXMuY2hhcmFjdGVyKFJlc3BvbnNlSWQpKSkgJT4lCiAgZmlsdGVyKEdlbmRlclNleCAlaW4lIGMoIkZlbWFsZSIsICJNYWxlIikpICU+JQogIG11dGF0ZShmYWN0b3IgPSBmYWN0b3IoZmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTVIxIiwgIk1SMyIsICJNUjIiLCAiTVI0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJjb2duaXRpb24gJiBjb250cm9sIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3NpdGl2ZSAmIHNvY2lhbCBlbW90aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJib2RpbHkgc2Vuc2F0aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuZWdhdGl2ZSBlbW90aW9ucyIpKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gR2VuZGVyU2V4LCB5ID0gc2NvcmUpKSArCiAgZmFjZXRfZ3JpZChmYWN0b3IgfiB0YXJnZXQsIHNjYWxlcyA9ICJmcmVlIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGx0eSA9IDIpICsKICAjIGdlb21faml0dGVyKGFscGhhID0gMC4wNSwgaGVpZ2h0ID0gMCkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gLiAlPiUgCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkodGFyZ2V0LCBmYWN0b3IsIEdlbmRlclNleCkgJT4lCiAgICAgICAgICAgICAgICAgICAgbXVsdGlfYm9vdF9zdGFuZGFyZChjb2wgPSAic2NvcmUiKSAlPiUKICAgICAgICAgICAgICAgICAgICB1bmdyb3VwKCksCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpLAogICAgICAgICAgICAgICAgICBmYXR0ZW4gPSAxLCBjb2xvciA9ICJibHVlIikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTEwLCAxMCwgMSkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSkpCmBgYAoKYGBge3J9CmdncGxvdChkX2RlbW8sIGFlcyh4ID0gZ3N1YignKC57MSwzMH0pKFxcc3wkKScsICdcXDFcbicsIFJhY2VFdGhuaWNpdHlfY29sbGFwc2UpKSkgKyAKICBnZW9tX2JhcigpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSkpICsKICBsYWJzKHRpdGxlID0gIlBhcnRpY3BpYW50IHJhY2UvZXRobmljaXR5IChzZWxmLXJlcG9ydGVkKSIsCiAgICAgICB4ID0gIlJhY2UvZXRobmljaXR5IiwKICAgICAgIHkgPSAiTnVtYmVyIG9mIHBhcnRpY2lwYW50cyIpCmBgYAoKYGBge3J9CmdncGxvdChkX2RlbW8sIGFlcyh4ID0gRmlyc3RMYW5nKSkgKyAKICBnZW9tX2JhcigpICsKICBsYWJzKHRpdGxlID0gIlBhcnRpY3BpYW50IGZpcnN0IGxhbmd1YWdlIChzZWxmLXJlcG9ydGVkKSIsCiAgICAgICB4ID0gIkxhbmd1YWdlIiwKICAgICAgIHkgPSAiTnVtYmVyIG9mIHBhcnRpY2lwYW50cyIpCmBgYAoKYGBge3J9CmdncGxvdChkX2RlbW8sIGFlcyh4ID0gZmFjdG9yKEVkdWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gbGV2ZWxzKGQkRWR1Y2F0aW9uKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gZ3N1YignKC57MSwzMH0pKFxcc3wkKScsICdcXDFcbicsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyhkJEVkdWNhdGlvbikpKSkpICsgCiAgZ2VvbV9iYXIoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpKSArCiAgbGFicyh0aXRsZSA9ICJQYXJ0aWNwaWFudCBlZHVjYXRpb25hbCBhdHRhaW5tZW50IChzZWxmLXJlcG9ydGVkKSIsCiAgICAgICB4ID0gIkhpZ2hlc3QgbGV2ZWwgb2YgZWR1Y2F0aW9uIGNvbXBsZXRlZCIsCiAgICAgICB5ID0gIk51bWJlciBvZiBwYXJ0aWNpcGFudHMiKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSAzLCBmaWcuYXNwID0gMX0KZWZhX2FsbF9wYXJfc2NvcmVzICU+JQogIG11dGF0ZShSZXNwb25zZUlkID0gYXMuY2hhcmFjdGVyKFJlc3BvbnNlSWQpKSAlPiUKICBsZWZ0X2pvaW4oZF9kZW1vICU+JSAKICAgICAgICAgICAgICBkaXN0aW5jdChSZXNwb25zZUlkLCBFZHVjYXRpb24pICU+JSAKICAgICAgICAgICAgICBtdXRhdGUoUmVzcG9uc2VJZCA9IGFzLmNoYXJhY3RlcihSZXNwb25zZUlkKSkpICU+JQogIG11dGF0ZShmYWN0b3IgPSBmYWN0b3IoZmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTVIxIiwgIk1SMyIsICJNUjIiLCAiTVI0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJjb2duaXRpb24gJiBjb250cm9sIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3NpdGl2ZSAmIHNvY2lhbCBlbW90aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJib2RpbHkgc2Vuc2F0aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuZWdhdGl2ZSBlbW90aW9ucyIpKSwKICAgICAgICAgaGlfbG93X2VkID0gY2FzZV93aGVuKAogICAgICAgICAgIGFzLm51bWVyaWMoRWR1Y2F0aW9uKSA8IDggfiAibGVzcyB0aGFuIEJBIiwKICAgICAgICAgICBhcy5udW1lcmljKEVkdWNhdGlvbikgPj0gOCB+ICJCQSBvciBtb3JlIiksCiAgICAgICAgIGhpX2xvd19lZCA9IGZhY3RvcihoaV9sb3dfZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPWMoImxlc3MgdGhhbiBCQSIsICJCQSBvciBtb3JlIikpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBoaV9sb3dfZWQsIHkgPSBzY29yZSkpICsKICBmYWNldF9ncmlkKGZhY3RvciB+IHRhcmdldCwgc2NhbGVzID0gImZyZWUiKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbHR5ID0gMikgKwogICMgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjA1LCBoZWlnaHQgPSAwKSArCiAgZ2VvbV9wb2ludHJhbmdlKGRhdGEgPSAuICU+JSAKICAgICAgICAgICAgICAgICAgICBncm91cF9ieSh0YXJnZXQsIGZhY3RvciwgaGlfbG93X2VkKSAlPiUKICAgICAgICAgICAgICAgICAgICBtdWx0aV9ib290X3N0YW5kYXJkKGNvbCA9ICJzY29yZSIpICU+JQogICAgICAgICAgICAgICAgICAgIHVuZ3JvdXAoKSwKICAgICAgICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCB5bWluID0gY2lfbG93ZXIsIHltYXggPSBjaV91cHBlciksCiAgICAgICAgICAgICAgICAgIGZhdHRlbiA9IDEsIGNvbG9yID0gImJsdWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDEwLCAxKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSkKYGBgCgpgYGB7cn0KZ2dwbG90KGRfZGVtbywgYWVzKHggPSBJbmNvbWUpKSArIAogIGdlb21fYmFyKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSkgKwogIGxhYnModGl0bGUgPSAiUGFydGljcGlhbnQgaG91c2Vob2xkIGluY29tZSAoc2VsZi1yZXBvcnRlZCkiLAogICAgICAgeCA9ICJBbm51YWwgaG91c2Vob2xkIGluY29tZSIsCiAgICAgICB5ID0gIk51bWJlciBvZiBwYXJ0aWNpcGFudHMiKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSAzLCBmaWcuYXNwID0gMX0KZWZhX2FsbF9wYXJfc2NvcmVzICU+JQogIG11dGF0ZShSZXNwb25zZUlkID0gYXMuY2hhcmFjdGVyKFJlc3BvbnNlSWQpKSAlPiUKICBsZWZ0X2pvaW4oZF9kZW1vICU+JSAKICAgICAgICAgICAgICBkaXN0aW5jdChSZXNwb25zZUlkLCBJbmNvbWUpICU+JSAKICAgICAgICAgICAgICBtdXRhdGUoUmVzcG9uc2VJZCA9IGFzLmNoYXJhY3RlcihSZXNwb25zZUlkKSkpICU+JQogIG11dGF0ZShmYWN0b3IgPSBmYWN0b3IoZmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTVIxIiwgIk1SMyIsICJNUjIiLCAiTVI0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJjb2duaXRpb24gJiBjb250cm9sIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3NpdGl2ZSAmIHNvY2lhbCBlbW90aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJib2RpbHkgc2Vuc2F0aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuZWdhdGl2ZSBlbW90aW9ucyIpKSwKICAgICAgICAgaGlfbG93X2luYyA9IGNhc2Vfd2hlbigKICAgICAgICAgICBhcy5udW1lcmljKEluY29tZSkgPCA0IH4gImxlc3MgdGhhbiAkNjAsMDAxIiwKICAgICAgICAgICBhcy5udW1lcmljKEluY29tZSkgPj0gNCB+ICIkNjAsMDAxIG9yIG1vcmUiKSwKICAgICAgICAgaGlfbG93X2luYyA9IGZhY3RvcihoaV9sb3dfaW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9YygibGVzcyB0aGFuICQ2MCwwMDEiLCAiJDYwLDAwMSBvciBtb3JlIikpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGhpX2xvd19pbmMpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBoaV9sb3dfaW5jLCB5ID0gc2NvcmUpKSArCiAgZmFjZXRfZ3JpZChmYWN0b3IgfiB0YXJnZXQsIHNjYWxlcyA9ICJmcmVlIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGx0eSA9IDIpICsKICAjIGdlb21faml0dGVyKGFscGhhID0gMC4wNSwgaGVpZ2h0ID0gMCkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gLiAlPiUgCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkodGFyZ2V0LCBmYWN0b3IsIGhpX2xvd19pbmMpICU+JQogICAgICAgICAgICAgICAgICAgIG11bHRpX2Jvb3Rfc3RhbmRhcmQoY29sID0gInNjb3JlIikgJT4lCiAgICAgICAgICAgICAgICAgICAgdW5ncm91cCgpLAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSwKICAgICAgICAgICAgICAgICAgZmF0dGVuID0gMSwgY29sb3IgPSAiYmx1ZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKC0xMCwgMTAsIDEpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZF9kZW1vLCBhZXMoeCA9IEhvdXNlaG9sZFNpemUpKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IG1lZGlhbihkX2RlbW8kSG91c2Vob2xkU2l6ZSksIGNvbG9yID0gImJsdWUiLCBsdHkgPSAyKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMDAwMCwgMSkpICsKICBsYWJzKHRpdGxlID0gIlBhcnRpY3BpYW50IGhvdXNlaG9sZCBzaXplIChzZWxmLXJlcG9ydGVkKSIsCiAgICAgICBzdWJ0aXRsZSA9ICJCbHVlIGRvdHRlZCBsaW5lIG1hcmtzIG1lZGlhbiIsCiAgICAgICB4ID0gIk51bWJlciBvZiBwZW9wbGUgaW4gaG91c2Vob2xkIChhZHVsdHMgYW5kIGNoaWxkcmVuKSIsCiAgICAgICB5ID0gIk51bWJlciBvZiBwYXJ0aWNpcGFudHMiKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZF9kZW1vLCBhZXMoeCA9IE1hcml0YWxTdGF0dXMpKSArIAogIGdlb21fYmFyKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSkgKwogIGxhYnModGl0bGUgPSAiUGFydGljcGlhbnQgbWFyaXRhbCBzdGF0dXMgKHNlbGYtcmVwb3J0ZWQpIiwKICAgICAgIHggPSAiTWFyaXRhbCBzdGF0dXMiLAogICAgICAgeSA9ICJOdW1iZXIgb2YgcGFydGljaXBhbnRzIikKYGBgCgpgYGB7cn0KZ2dwbG90KGRfZGVtbywgYWVzKHggPSBQYXJlbnQpKSArIAogIGdlb21fYmFyKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSkgKwogIGxhYnModGl0bGUgPSAiUGFydGljcGlhbnQgcGFyZW50IHN0YXR1cyAoc2VsZi1yZXBvcnRlZCkiLAogICAgICAgc3VidGl0bGUgPSAiJ05BJyBpbmRpY2F0ZXMgcmVzcG9uc2Ugb2YgJ1ByZWZlciBub3QgdG8gc2F5JyIsCiAgICAgICB4ID0gIlBhcmVudCBzdGF0dXMiLAogICAgICAgeSA9ICJOdW1iZXIgb2YgcGFydGljaXBhbnRzIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gMywgZmlnLmFzcCA9IDF9CmVmYV9hbGxfcGFyX3Njb3JlcyAlPiUKICBtdXRhdGUoUmVzcG9uc2VJZCA9IGFzLmNoYXJhY3RlcihSZXNwb25zZUlkKSkgJT4lCiAgbGVmdF9qb2luKGRfZGVtbyAlPiUgCiAgICAgICAgICAgICAgZGlzdGluY3QoUmVzcG9uc2VJZCwgUGFyZW50KSAlPiUgCiAgICAgICAgICAgICAgbXV0YXRlKFJlc3BvbnNlSWQgPSBhcy5jaGFyYWN0ZXIoUmVzcG9uc2VJZCkpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKFBhcmVudCkpICU+JQogIG11dGF0ZShmYWN0b3IgPSBmYWN0b3IoZmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTVIxIiwgIk1SMyIsICJNUjIiLCAiTVI0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJjb2duaXRpb24gJiBjb250cm9sIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3NpdGl2ZSAmIHNvY2lhbCBlbW90aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJib2RpbHkgc2Vuc2F0aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuZWdhdGl2ZSBlbW90aW9ucyIpKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gUGFyZW50LCB5ID0gc2NvcmUpKSArCiAgZmFjZXRfZ3JpZChmYWN0b3IgfiB0YXJnZXQsIHNjYWxlcyA9ICJmcmVlIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGx0eSA9IDIpICsKICAjIGdlb21faml0dGVyKGFscGhhID0gMC4wNSwgaGVpZ2h0ID0gMCkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gLiAlPiUgCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkodGFyZ2V0LCBmYWN0b3IsIFBhcmVudCkgJT4lCiAgICAgICAgICAgICAgICAgICAgbXVsdGlfYm9vdF9zdGFuZGFyZChjb2wgPSAic2NvcmUiKSAlPiUKICAgICAgICAgICAgICAgICAgICB1bmdyb3VwKCksCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpLAogICAgICAgICAgICAgICAgICBmYXR0ZW4gPSAxLCBjb2xvciA9ICJibHVlIikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTEwLCAxMCwgMSkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSkpCmBgYAoKYGBge3J9CmdncGxvdChkX2RlbW8gJT4lIGZpbHRlcihQYXJlbnQgPT0gIlllcyIpLCBhZXMoeCA9IENoaWxkcmVuTnVtYmVyKSkgKyAKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBtZWRpYW4oZF9kZW1vW2RfZGVtbyRQYXJlbnQgPT0gIlllcyIsXSRDaGlsZHJlbk51bWJlciwgbmEucm0gPSBUKSwgCiAgICAgICAgICAgICBjb2xvciA9ICJibHVlIiwgbHR5ID0gMikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoLTEsIDEwMDAwLCAxKSkgKwogIGxhYnModGl0bGUgPSAiTnVtYmVyIG9mIGNoaWxkcmVuIGFtb25nIHBhcmVudHMgKHNlbGYtcmVwb3J0ZWQpIiwKICAgICAgIHN1YnRpdGxlID0gIkJsdWUgZG90dGVkIGxpbmUgbWFya3MgbWVkaWFuIiwKICAgICAgIHggPSAiTnVtYmVyIG9mIGNoaWxkcmVuIChhbW9uZyBwYXJlbnRzKSIsCiAgICAgICB5ID0gIk51bWJlciBvZiBwYXJ0aWNpcGFudHMiKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZF9kZW1vICU+JSBmaWx0ZXIoUGFyZW50ID09ICJZZXMiKSwgCiAgICAgICBhZXMoeCA9IGZhY3RvcihDaGlsZHJlbk9sZGVzdEFnZV9jb2xsYXBzZSwKICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGxldmVscyhkX2RlbW8kQ2hpbGRyZW5PbGRlc3RBZ2VfY29sbGFwc2UpLAogICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gZ3N1YignKC57MSwzMH0pKFxcc3wkKScsICdcXDFcbicsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMoZF9kZW1vJENoaWxkcmVuT2xkZXN0QWdlX2NvbGxhcHNlKSkpKSkgKyAKICBnZW9tX2JhcigpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSkpICsKICBsYWJzKHRpdGxlID0gIkFnZSBvZiBvbGRlc3QgY2hpbGQgYW1vbmcgcGFyZW50cyAoc2VsZi1yZXBvcnRlZCkiLAogICAgICAgeCA9ICJBZ2Ugb2YgY2hpbGQgaW4geWVhcnMgKGFtb25nIHBhcmVudHMpIiwKICAgICAgIHkgPSAiTnVtYmVyIG9mIHBhcnRpY2lwYW50cyIpCmBgYAoKYGBge3J9CmdncGxvdChkX2RlbW8gJT4lIGZpbHRlcihQYXJlbnQgPT0gIlllcyIpLCAKICAgICAgIGFlcyh4ID0gZmFjdG9yKENoaWxkcmVuWW91bmdlc3RBZ2VfY29sbGFwc2UsCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBsZXZlbHMoZF9kZW1vJENoaWxkcmVuWW91bmdlc3RBZ2VfY29sbGFwc2UpLAogICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gZ3N1YignKC57MSwzMH0pKFxcc3wkKScsICdcXDFcbicsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMoZF9kZW1vJENoaWxkcmVuWW91bmdlc3RBZ2VfY29sbGFwc2UpKSkpKSArIAogIGdlb21fYmFyKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSkgKwogIGxhYnModGl0bGUgPSAiQWdlIG9mIHlvdW5nZXN0IGNoaWxkIGFtb25nIHBhcmVudHMgKHNlbGYtcmVwb3J0ZWQpIiwKICAgICAgIHggPSAiQWdlIG9mIGNoaWxkIGluIHllYXJzIChhbW9uZyBwYXJlbnRzKSIsCiAgICAgICB5ID0gIk51bWJlciBvZiBwYXJ0aWNpcGFudHMiKQpgYGAKCiMgU2F2ZSBFRkEgb3V0cHV0CgpGaW5hbGx5LCBJJ2xsIGV4cG9ydCB0aGUgNC1mYWN0b3IgRUZBIHJlc3VsdHMgdG8gYSBzYXZlZCBmaWxlIHRoYXQgSSBjYW4gZHJhdyBvbiBpbiBvdXIgU3R1ZHkgMiBhbmFseXNlcy4KCmBgYHtyfQpzYXZlUkRTKGVmYV9hbGxfcGFyLCBmaWxlID0gIi4vczFfZWZhLnJkcyIpCndyaXRlLmNzdihkX2RlbW8sIGZpbGUgPSAiLi9zMV9kZW1vLmNzdiIpCndyaXRlLmNzdihkX2FsbCwgZmlsZSA9ICIuL3MxX2RhdGEuY3N2IikKYGBgCgo=